주요 콘텐츠로 건너뛰기
AI 튜토리얼

Handwired: JavaScript 프로그램을 미분 가능한 신경망으로 변환하기

이 튜토리얼에서는 조건문, 반복문, 프로그램 상태를 행렬 곱셈과 ReLU 방식의 연산으로 변환하는 Handwired의 접근 방식을 설명합니다. Bun으로 프로젝트를 설정하고 데모를 살펴보며, 산술 변환을 이해하고 미분 가능한 프로그램이 유용한 분야를 알아봅니다.

Handwired: JavaScript 프로그램을 미분 가능한 신경망으로 변환하기

Handwired란?

Handwired는 학습이 필요하지 않은 방식으로 일반 JavaScript 코드를 신경망과 유사한 계산으로 변환합니다. 프로그램을 일반적인 제어 흐름으로 표현하는 대신 조건문, 반복문, 상태와 같은 로직을 부동소수점 값에 대한 행렬 곱셈과 reglu 연산으로 변환합니다.

변환된 프로그램은 완전히 미분 가능한 상태로 유지되며, 가중치는 학습되는 대신 수동으로 작성됩니다. Handwired는 JavaScript 또는 WebGPU를 사용해 이러한 계산을 실행할 수 있습니다.

HandwiredOS 데모

프로그램을 신경 계산으로 변환하는 이유

Handwired는 프로그램의 동작을 주로 덧셈, 곱셈, ReLU 방식의 연산으로 이루어진 소수의 수학적 기본 연산으로 단순화합니다. 이 방식은 다음과 같은 흥미로운 특성을 제공합니다.

  • 전체 프로그램이 미분 가능한 상태로 유지됩니다.
  • 가중치를 수동으로 작성하므로 학습할 필요가 없습니다.
  • 퓨전, 희소성, 연산 재배치와 같은 GPU 최적화를 단순화된 계산에 적용할 수 있습니다.
  • 기존 JavaScript 코드를 이러한 형태로 표현하면 GPU 수준의 병렬성을 구현할 가능성이 있습니다.

이 프로젝트는 실험적인 가능성도 제공합니다. 수동으로 정의한 가중치의 고정을 해제하고 학습이 어떤 결과를 만들어 내는지 살펴보거나, 고정된 프로그램을 일반 신경망에 연결해 결합된 시스템을 엔드 투 엔드로 학습시킬 수 있습니다.

프로젝트 설정

Handwired에는 구현을 로컬에서 살펴볼 수 있는 라이브 데모와 소스 코드가 포함되어 있습니다. 시스템에 Bun이 설치되어 있어야 합니다.

  1. Handwired 저장소를 복제합니다.
  2. 프로젝트 디렉터리로 이동합니다.
  3. bun install로 의존 항목을 설치합니다.
  4. bun start로 로컬 데모를 시작합니다.
git clone <handwired-repository-url>
cd handwired
bun install
bun start

프로젝트를 시작한 후 Bun이 출력한 로컬 주소를 사용해 데모를 확인합니다. chenglou.me/handwired에서 호스팅된 데모를 실행해 볼 수도 있습니다.

핵심 변환 이해하기

간단한 JavaScript 조건문을 살펴보겠습니다.

const a = 5
const result = (a > 4) ? 10 : 12

Handwired는 산술 연산으로 조건을 표현합니다. 정수 값의 경우 다음과 같은 ReLU 연산의 차이를 사용하면 a > 4일 때 1이고 a <= 4일 때 0인 선택자를 만들 수 있습니다.

const a = 5
const above4 = Math.max(0, a - 4) - Math.max(0, a - 5)
const result = above4 * 10 + (1 - above4) * 12

두 분기를 모두 계산하지만 above4가 적절한 결과를 선택합니다. a = 5이면 선택자는 1이므로 최종 값은 10이며, 이는 원래 조건식과 일치합니다.

수학적 표현의 작동 방식

핵심 아이디어는 분기 처리를 연속적인 산술 기본 연산으로 대체하는 것입니다. 조건문은 다음 연산의 조합으로 변환됩니다.

HandwiredOS

  • 입력에서 선택자를 구성하는 ReLU 연산
  • 각 분기에 선택자를 적용하는 곱셈
  • 분기 결과를 결합하는 덧셈

이러한 연산을 모으면 Handwired는 관련 활성화 연산이 포함된 큰 행렬 곱셈으로 계산을 표현할 수 있습니다. 그러면 동일한 프로그램을 JavaScript 또는 WebGPU를 사용해 평가할 수 있습니다.

두 분기가 모두 계산되고, 선택자가 출력에 기여할 결과를 결정합니다.

저장소 살펴보기

프로젝트를 살펴볼 때는 README에서 강조하는 다음 디렉터리부터 확인하세요.

  • docs/에는 프로젝트를 이해하는 데 필요한 문서와 자료가 있습니다.
  • src/에는 구현이 들어 있습니다.
  • template/에는 프로젝트에 익숙해지기 위한 시작점이 제공됩니다.
  • lab/에는 살펴보거나 건너뛸 수 있는 오래된 실험이 들어 있습니다.

실용적인 작업 흐름은 먼저 데모를 실행한 다음 관련 소스 파일과 동작을 비교하는 것입니다. 이렇게 하면 눈에 보이는 예제와 행렬 연산으로 변환되는 내부 과정을 연결해 이해할 수 있습니다.

데모 실행하기

호스팅된 데모는 Handwired의 작동 방식을 가장 빠르게 확인할 수 있는 방법입니다. 프로젝트 설명에서는 100,000개의 문서를 밀리초 단위로 처리하는 JSON 검색 데모를 특히 강조합니다. 이 데모는 전통적인 단일 스레드 방식으로 작성된 코드에 상당한 병렬성을 제공한다는 프로젝트의 목표를 보여 줍니다.

데모를 사용해 원래 프로그램 구조와 생성된 수학적 표현의 차이를 확인하세요. 로컬 소스를 수정하기 전에 시작점으로 활용하기에도 좋습니다.

고급 아이디어

학습 가능한 가중치 실험

Handwired는 일반적으로 수동으로 작성한 가중치를 사용하므로 프로그램을 작동시키기 위해 학습이 필요하지 않습니다. 프로젝트에서 제안하는 한 가지 실험은 이러한 가중치의 고정을 해제하고 최적화 과정이 어떤 결과를 만들어 내는지 확인하는 것입니다.

고정된 프로그램과 신경망 결합

또 다른 가능성은 특정한 고정 Handwired 프로그램을 일반 신경망에 연결하고 결합된 시스템을 엔드 투 엔드로 학습시키는 것입니다. 이렇게 하면 모델이 정밀하게 정의된 프로그램을 유지하면서 다른 동작을 학습할 수 있습니다.

기본 연산 관점에서 생각하기

실험을 설계할 때는 제어 흐름을 덧셈, 곱셈, ReLU 방식의 연산으로 표현하는 방법에 집중하세요. 결과 계산이 단순할수록 퓨전, 희소성, 재배치와 같은 기법의 이점을 직접적으로 활용할 수 있습니다.

결론

Handwired는 일반적인 JavaScript 로직을 미분 가능한 수학적 계산으로 다시 작성하는 방법을 보여줍니다. 제어 흐름을 산술 선택자로 대체하고 결과를 행렬 곱셈과 활성화 연산으로 축소함으로써, 기존 프로그램을 신경망 기법과 JavaScript 또는 WebGPU 실행 환경과 호환되게 만듭니다. Bun으로 설치하고 데모를 살펴본 다음 docs/, src/, template/을 확인하며 실험을 시작해 보세요.