BLOG
handwired:JSコードを無理やりニューラルネットワークとして実装する
10月15日、ReactチームのメンバーchenglouがGitHubでhandwiredを公開しました。READMEの最初の文は「Regular JavaScript codeをNeural netに変換する;訓練不要、正確で、しかも完全に微分可能」です。通常のJavaScriptコードをニューラルネットワークに変換し、訓練なしで正確な結果を得られ、全過程が微分可能です。10月20日までに、リポジトリには1804★のいいねが集まり、注目は主にGitHubのtrendingやソーシャルメディアから来ており、HNでも何度もトップページに掲載されました。このプロジェクトはTypeScriptで書かれており、MITライセンスに基づいています。ビルドツールはbunで、オンラインデモはchenglou.me/handwiredにあります。ローカルではbun install && bun startで実行できます。この記事では6段階で分解します。
このプロジェクトの特徴は、「ネットワークを訓練してシミュレーションする」という従来の方法を踏まない点です。逆に、まずプログラムを書き、それをニューラルネットワークが実行できる形式にコンパイルします。この逆操作により、ニューラルネットワークは「学習器」から「実行器」へと変わります。
一、作者について
著者chenglouは、GitHubで有名な開発者であり、Reactチームのメンバーです。今回、個人プロジェクトとしてhandwiredを公開しました。labディレクトリの実験記録から、9月初旬には日々更新される実験ログがあり、6月と7月の設計議論も記載されており、公開前に長い準備期間があったことがわかります。公開後、短期間で頻繁にコミットされたのは、「長期の準備の後に一度に公開し、継続的に整理する」という意味であり、全工程を一度に完成させたわけではありません。この公開スピードはオープンソースコミュニティでは珍しくありません。まず内々で磨き上げ、その後一度に公開し、ソーシャルメディアを利用して初期の注目を集めます。
プロジェクトの規模について、核心のsrc/ディレクトリにはruntime、handwiredos、json-searchなどのサブモジュールが含まれています。重要なファイルのサイズは以下の通りです:src/runtime/numeric-ui-core.ts約152KB、src/runtime/cells.ts約22KB、src/runtime/host-timing.ts約21KB。リポジトリ全体のTypeScriptの割合は90.5%で、ドキュメント、テスト、オンラインデモを含む完全なプロジェクトであり、gistレベルの概念デモではありません。その目標は、また別のフロントエンドフレームワークになることではなく、「プログラム即ちネットワーク」という概念に実行可能な参照実装を提供することです。differential programmingを迅速に理解したい開発者にとって、このリポジトリは直接クローンし、実行し、変更するための出発点を提供します。
二、メカニズムの分解
handwiredの出発点は、どんなプログラムも基本的にはif-else、ループ、状態を持っていることです。そして、これら3つの要素を「行列乗算 + ReLU」という形式で浮動小数点数上で実行するように変換します。
READMEに示されている例が最も直感的です。(a > 4) ? 10 : 12のような分岐は、純粋な算術に置き換えることができます:
above4 = max(0, a - 4) - max(0, a - 5) // a > 4の場合は1、そうでない場合は0
result = above4 * 10 + (1 - above4) * 12 // 2つの分岐を計算し、above4で結果を選択
ここでのmax(0, x)がReLUです。比較や選択のような制御フローを、加算、乗算、除算、ReLUという形式にエンコードします。ループと状態も同様です:状態はFloat32Arrayのソーステーブルに格納され、各ラウンドでテーブルを読み込み、計算し、戻します。
全体のコンパイルプロセスを連携させるために、handwiredは構築時には通常のJavaScriptを実行し、emitMultiply、emitCompareなどのマクロを固定長の命令に展開します。実行時には分岐やループがなく、浮動小数点テーブルに対する順序的な計算のみがあります。これにより、プログラムがコンパイルされた後、その実行パスは決定されており、GPUは一括で多数の同型スレッドをスケジュールでき、実行時の動的な分岐処理を行う必要がありません。
次のステップは収集です:プログラム内のすべての加算、乗算、ReLUを巨大なmatmulにまとめ、JSやWebGPU上で実行します。基本的にこれら2つの演算子のみを使用するため、READMEには3つの性質が示されています:プログラム全体が微分可能であり、重みは手書きで、訓練の必要はなく、GPUの成熟した最適化技術がこの極簡素な演算子に特に効果的です。
プロジェクトの核心的な革新点は、プログラムを近似するネットワークを訓練するのではなく、手書きのプログラムを正確にニューラルネットワークの形にコンパイルすることです。重みは訓練の結果ではなく、プログラムそのものです。この「訓練不要、正確、微分可能」という3つの目標が同時に達成され、それはコンパイルの方向性の選択によって実現されています。言い換えれば、ここでのニューラルネットワークは、データから学習された近似関数ではなく、プログラムの実行形式のようなものです。
このアプローチの価値は、「微分可能」という性質を訓練段階からコンパイル段階に移した点にあります。従来のニューラルネットワークでは大量のデータとバックプロパゲーションが必要で、重みを調整します。handwiredでは、まずプログラムの論理で確定的な行動を記述し、その後、必要に応じて最適化器に接続できるように勾配構造を保持します。これは訓練を置き換えるものではなく、「訓練」と「プログラム」の境界を一歩後ろに押し出すものです。
三、エンジニアリングの質
ディレクトリ構造から見ると、src/は核心のruntime、lab/は実験プロジェクト、template/はテンプレート、docs/はドキュメントです。runtime部分は、特にcells、host-timing、numeric-ui-coreなどのファイルが主で、その中のnumeric-ui-core.tsという単一ファイルは約152KBで、数値/UIのruntimeの基幹部分です。
仓库のTypeScriptの割合が90.5%に達していることから、これは軽量なパッケージではなく、数値計算、アニメーションスケジューリング、ホストインタラクションをすべて内包したエンジニアリングであることがわかります。docs/のドキュメントでは、実行モデル、チュートリアル、パターン、ビヘイヴィースルーティングを網羅しており、微分可能なプログラミングを理解したい人にとって非常に便利です。このようなエンジニアリングの密度は、handwiredが一日や二日のアイデアから生まれたものではなく、何度も反復を経て形成されたシステムであることを示しています。
依存関係を見ると、handwiredは重要なランタイムを導入していません。package.jsonにはTypeScript、テスト、lintツールのみが含まれており、核心ロジックは完全に自己完結しています。この選択により、ワークロードは軽量に保たれていますが、現在はbuilder APIで表現可能なプログラムセグメントのみをカバーしていることを意味します。既存の大規模ビジネスシステムへの直接移行は現実的ではなく、より現実的な方法は部分的な計算集約型セグメントを抽出して再構築することです。ソースコードの構成において、tests/ディレクトリとtemplate/ディレクトリが並列に配置されていることから、作者はユーザーがテンプレートから始めて、普通のJSをhandwiredスタイルに徐々に変換することを望んでいることがわかります。
オンラインデモとtemplate/ディレクトリ内の例が最も直感的な入り口です:普通のJSで書かれたUIコンポーネントが、handwiredのbuilderコードによって変換されると、GPU上で実行可能な数値テーブルになります。構築時には普通のJavaScriptを一度実行し、emitMultiply、emitCompareなどのマクロを固定長の命令に展開します。実行時にはどんなブリッジやループもありません。
このような書き方はフロントエンドエンジニアにとって自然な親しみやすさがあります:CUDAを書く必要もなく、WGSLを書く必要もなく、JavaScriptのbuilderAPIで数値計算を記述するだけで、残りの展開、収集、実行はhandwiredが行います。Reactの声明式コンポーネントに慣れている人にとっては、「コンポーネントツリー」を「数値プログラム図」に置き換えることになりますが、インターフェースの書き方は依然としてJavaScriptです。これはまた、フロントエンドエンジニアが自分が最も慣れている言語を使ってGPUの並列性や微分可能なプログラミングを探求できることを意味し、新しい言語を学ぶよりも入門障壁が低いということです。
しかし、builderAPIの親しみやすさは制限ももたらしています:すべての計算はプロジェクトが提供するプリミティブで表現できなければならず、範囲を超える操作は普通のJavaScriptで処理する必要があります。handwiredはJSに埋め込まれた特定分野の言語のようなものであり、JS文法の無差別な翻訳ではありません。
四、効果と検証
倉庫自述の効果は3つの層に分かれています。第一層は概念検証です:if-else、ループ、状態を行列乗算とReLUに変換し、プログラムは依然として正確で微分可能です。第二層はデモンストレーションです:オンラインデモでは、完全なUIデスクトップシステムであるHandwiredOSが展示されており、ウィンドウのドラッグアンドドロップ、最大化、クリック選択、テキストの改行、仮想スクロールリストなどのインタラクションが数値プログラムに組み込まれています。ホストはブラウザのイベントをソーステーブルに書き込み、一度評価して出力をDOMに戻すだけです。第三層は性能宣言です:JSON検索デモでは、10万件のドキュメントをミリ秒単位で処理できると主張されており、その成果は同構並列性によるもので、つまり各ドキュメントに対して同じ操作が行われ、互いに干渉しません。言い換えれば、handwiredのデモの価値は、「プログラムが浮動小数点テーブル上で実行できる」という事実を証明する点にあります。これは単なる理論的な可能性ではなく、実際に可能であることを示しています。抽象概念をブラウザ内でクリック可能なデモにすることで、高い評価を得ている重要な理由です。
しかし、著者自身はこれらを実験的なものと位置づけています。READMEの「what does that even do? Let’s find out!」というスタイルや、「凍結された特定のプログラムを汎用ニューラルネットワークのエンドツーエンドトレーニングに接続し、nanoGPTはシェイクスピアとあなたのUIを同時に学習できるのか?」といった質問から、これが成熟したツールではなく、探索的なプロジェクトであることがわかります。
五、境界と論争
まず言うべきは表現の境界です。READMEの「Turn your regular JavaScript code into a neural net」という文は、任意のJSをネットワークに自動変換できると誤解されやすいです。しかし、技術的現実として、プロジェクトが提供するビルダーリテールと数値契約を使って手動でプログラムを書き直す必要があり、汎用JSコンパイラではありません。
次に数値の境界です。ReLUを用いた整数のエンコーディングは、操作数が宣言されたグリッドと範囲内にあるかどうかに依存します。浮動小数点世界では、範囲を超える入力には魔法はありません。インデックスの読み取りにも範囲制限があります。プログラムを書く人は、これらの数値契約を自ら維持する必要があります。
第三に規模の境界です。両側で計算を行うため、操作数はプログラムの複雑さが増すにつれて増加します。handwiredは「プログラム即ネットワーク」という方向性を検証するのに適していますが、実際のビジネスシステムの制御流れをすべて行列操作に展開すると、規模とデバッグコストが急速に増加します。これはまた、handwiredが現在、コントロール、検索、アニメーションなどの局部的な計算集約型シナリオに適していることを意味し、全体のビジネスロジックには適していないということです。
最後にエコシステムの境界です。新しく発表された実験プロジェクトとして、handwiredはまだ安定したコミュニティやツールチェーンを形成していません。サードパーティのライブラリ、エディタープラグイン、デバッグツールは未成熟であり、企業が導入を検討する場合、維持コストと認識コストを同時に負担しなければなりません。
最後に、伝播と人気の間の温度差です。GitHub上での評価は1804★と高く、HNも何度もトップページに掲載されています。しかし、高い評価は話題性をより多く測定するものであり、実際の採用度ではありません。インターフェースはいつ変更されるかわかりませんし、open issuesも増加しています。現在、実用的なツールを探している人は、直接採用するべきではありません。
六、結論
handwiredの価値は、具体的な実行可能なプログラムを使って、「通常のプログラムを微分可能なニューラルネットワークにコンパイルできる」という概念をスローガンからデモレベルに落とし込んだ点にあります。これは、「ニューラルネットワークは必ず訓練する必要がある」という既定の認識に挑戦し、微分可能性はコンパイル構造から自然に生まれるものであり、必ずしもバックプロパゲーションによって外部から注入される必要はないことを示しています。この考え方は、現在多くのAIプロジェクトが訓練データに依存している状況において、補完的な役割を果たします。特定のシナリオでは、プログラム自体の構造だけで微分可能性を実現でき、問題をすべて最適化問題としてモデル化する必要はありません。
4天冲上 1804★は、このトピックがコミュニティの好奇心を刺激したことを示しています。しかし、これが研究用の玩具なのか、あるいは新しいパラダイムのシグナルなのかを判断するには、今後誰かがこれを実際のアプリケーションに応用したり、この方法をより複雑な制御フローに拡張できるかどうかが重要です。現段階では、これは新世代のフロントエンドフレームワークとして直接使用するのではなく、微分可能なプログラミングと数値コンパイルを理解するための教材としての入り口として適しています。フロントエンドやコンパイラの開発者にとって、handwiredは注目すべきプログラム表現方法を提供します。直接応用を望むチームにとっては、さらに多くの検証とエコシステム構築が必要です。
興味深い比較対象は従来のニューラルネットワークです。従来のネットワークは訓練を通じて重みを探索しますが、その利点は汎用性があることですが、欠点は行動が解釈不可能であり、大量のデータが必要であることです。handwiredはプログラムを使って直接重みを指定しますが、その利点は行動が確定しており解釈可能であることですが、欠点は表現能力がプログラマーの書けるプログラムに制限されることです。両者は代替関係ではなく、補完関係です。説明可能性と確実性が高く求められるシナリオ、例えばUIアニメーション、金融計算、物理シミュレーションなどでは、handwiredの考え方が訓練ネットワークよりも信頼性が高いかもしれません。
これは明日のコーディングスタイルを変えるわけではありませんが、「プログラムとネットワークの間の壁」を再び壊すことになりました。今後の注目すべき問題には、より動的な制御フローをサポートできるか、微分可能性を保ちつつ規模の膨張を減らすことができるか、既存のフロントエンドフレームワークと補完的でなく代替的な関係を築けるかが含まれます。これらの問題にはすぐに答えはありませんが、それらの問題があるからこそ、handwiredは議論の価値を持ち続けているのです。
情報源
- GitHubリポジトリ:chenglou/handwired(README、docs、src、lab)
- 事実パッケージ:/Users/kael/xhs-content/drafts/2026-10-20-facts-packages.json(リポジトリの規模、作者、核心メカニズム、Demoアドレス、伝播力)
- オンラインデモ:https://chenglou.me/handwired/