世界を動かす技術を、日本語で。

RustGPT: ゼロから構築された純粋なRust製トランスフォーマーLLM

概要

RustGPTは、 外部MLフレームワーク不使用 でRustのみを用いてLLM(大規模言語モデル)を一から実装したプロジェクト。 ndarray ライブラリによる行列演算のみを使用。 トランスフォーマーベース のアーキテクチャを採用し、学習から対話まで一貫した機能を提供。 学習・推論・テスト がRust環境のみで完結。 教育・実験・拡張 に最適な構成。

RustGPT: Pure RustによるLLM実装

  • Rustのみ でLLMを一から構築したプロジェクト
  • 外部MLフレームワーク完全排除 (PyTorch, TensorFlow, Candle等不使用)
  • ndarray による行列演算のみ使用
  • トランスフォーマーアーキテクチャ の実装
  • 事実ベースの事前学習会話指向のInstruction Tuning を搭載
  • 対話型テストモード による即時検証

主な構成ファイル

  • src/main.rs :学習パイプライン、データ準備、対話モード
  • src/llm.rs :LLMのコア実装(順伝播・逆伝播・学習ロジック)

モジュール構成

  • embeddings.rs :トークン埋め込み層
  • transformer.rs :トランスフォーマーブロック(自己注意+FFN)
  • self_attention.rs :マルチヘッド自己注意
  • feed_forward.rs :位置ごとのフィードフォワード
  • output_projection.rs :出力線形層(語彙予測)
  • vocab.rs :語彙管理・トークナイザー
  • layer_norm.rs :レイヤーノルム
  • adam.rs :Adamオプティマイザ

テストカバレッジ

  • 各コンポーネントごとに 専用テストファイル を用意
    • llm_test.rs :LLM全体
    • transformer_test.rs :トランスフォーマーブロック
    • self_attention_test.rs :自己注意
    • feed_forward_test.rs :FFN
    • embeddings_test.rs :埋め込み
    • vocab_test.rs :語彙
    • adam_test.rs :オプティマイザ
    • output_projection_test.rs :出力層

RustGPTの学習プロセス

  • 事前学習 :事実文の完了タスクで世界知識を獲得
    • 例:「The sun rises in the east and sets in the west」
  • Instruction Tuning :会話形式での応答パターンを学習
    • 例:「User: How do mountains form? Assistant: Mountains are formed through tectonic forces...」
  • 挨拶・説明・フォローアップ など多様な対話パターンに対応

クイックスタート

  • リポジトリクローン
    git clone https://github.com/tekaratzas/RustGPT.git
    cd RustGPT
    cargo run
    
  • 実行時フロー
    • 語彙構築
    • 事前学習(100エポック)
    • Instruction Tuning(100エポック)
    • 対話モード突入

対話モード例

  • 入力例:「How do mountains form?」
  • 出力例:「Mountains are formed through tectonic forces or volcanism over long geological time periods」
  • 入力例:「What causes rain?」
  • 出力例:「Rain is caused by water vapor in clouds condensing into droplets that become too heavy to remain airborne」

技術仕様・特徴

  • 語彙サイズ :学習データから動的生成
  • 埋め込み次元数 :128
  • 隠れ層次元数 :256
  • 最大系列長 :80トークン
  • 構成 :3トランスフォーマーブロック+埋め込み+出力層
  • オプティマイザ :Adam(勾配クリッピング有)
  • 事前学習LR :0.0005(100エポック)
  • Instruction Tuning LR :0.0001(100エポック)
  • 損失関数 :クロスエントロピー
  • 勾配クリッピング :L2ノルム5.0で制限

実装上の工夫

  • 独自トークナイザー (句読点考慮)
  • グリーディデコーディング によるテキスト生成
  • 勾配クリッピング で学習安定化
  • モジュラー設計 で拡張容易
  • 全コンポーネントにテスト実装

開発・テスト

  • 全体テスト:cargo test
  • 個別テスト例:cargo test --test llm_test
  • 最適化ビルド:cargo build --release
  • 詳細出力付きテスト:cargo test -- --nocapture

RustGPTで学べるML概念

  • トランスフォーマーアーキテクチャ (注意機構・FFN・LayerNorm)
  • ニューラルネットワークの逆伝播
  • 言語モデル学習 (事前学習+微調整)
  • トークナイザー・語彙管理
  • Adamによる勾配最適化

依存関係

  • ndarray :多次元配列・行列演算
  • rand/rand_distr :初期化用乱数生成
  • 外部MLフレームワーク一切不使用

コントリビューションガイド

  • 貢献歓迎。学習・実験に最適なプロジェクト
  • 優先度高:
    • モデル永続化 (パラメータ保存/読込)
    • 性能最適化 (SIMD、並列学習、メモリ効率化)
    • 高度なサンプリング (ビームサーチ、top-k/p、温度制御)
    • 評価指標 (パープレキシティ、ベンチマーク、可視化)
  • 改善分野:
    • 高度なアーキテクチャ (多頭注意、位置エンコーディング、RoPE)
    • 学習手法拡張 (最適化手法、LRスケジューリング、正則化)
    • データ処理強化 (大規模データ、トークナイザー改良、ストリーミング対応)
    • モデル解析 (注意可視化、勾配解析、解釈性)

貢献方法

  • リポジトリをFork
  • フィーチャーブランチ作成 git checkout -b feature/model-persistence
  • 変更&テスト追加
  • テスト実行:cargo test
  • プルリクエスト送信(説明明記)

コードスタイル

  • 標準Rust規約 (cargo fmt)遵守
  • 新機能にはテスト追加必須
  • ドキュメント・README更新
  • 「from scratch」哲学維持 (重厚なML依存回避)

貢献アイデア例

  • 初級 :モデル保存/読込、学習データ追加、設定ファイル対応
  • 中級 :ビームサーチ、位置エンコーディング、学習チェックポイント
  • 上級 :多頭注意、レイヤ並列化、独自最適化

サポート

  • Issueやディスカッション で質問・提案受付
  • 外部MLフレームワーク不使用 を徹底

RustGPTは、 Rustのみ でLLMの仕組みを深く理解・体験できる最良の教材・実験基盤。 機械学習の基礎から応用まで をRustで学びたい方に最適なプロジェクト。

Hackerたちの意見

ndarray = "0.16.1" rand = "0.9.0" rand_distr = "0.5.0" いい感じだね!

ちょっと気になったんだけど、cargo tree llm v0.1.0 (RustGPT) ├── ndarray v0.16.1 │ ├── matrixmultiply v0.3.9 │ │ └── rawpointer v0.2.1 │ │ [build-dependencies] │ │ └── autocfg v1.4.0 │ ├── num-complex v0.4.6 │ │ └── num-traits v0.2.19 │ │ └── libm v0.2.15 │ │ [build-dependencies] │ │ └── autocfg v1.4.0 │ ├── num-integer v0.1.46 │ │ └── num-traits v0.2.19 () │ ├── num-traits v0.2.19 () │ └── rawpointer v0.2.1 ├── rand v0.9.0 │ ├── rand_chacha v0.9.0 │ │ ├── ppv-lite86 v0.2.20 │ │ │ └── zerocopy v0.7.35 │ │ │ ├── byteorder v1.5.0 │ │ │ └── zerocopy-derive v0.7.35 (proc-macro) │ │ │ ├── proc-macro2 v1.0.94 │ │ │ │ └── unicode-ident v1.0.18 │ │ │ ├── quote v1.0.39 │ │ │ │ └── proc-macro2 v1.0.94 () │ │ │ └── syn v2.0.99 │ │ │ ├── proc-macro2 v1.0.94 () │ │ │ ├── quote v1.0.39 () │ │ │ └── unicode-ident v1.0.18 │ │ └── rand_core v0.9.3 │ │ └── getrandom v0.3.1 │ │ ├── cfg-if v1.0.0 │ │ └── libc v0.2.170 │ ├── rand_core v0.9.3 () │ └── zerocopy v0.8.23 └── rand_distr v0.5.1 ├── num-traits v0.2.19 () └── rand v0.9.0 () うん、まだまだ見た目はいい感じだね。

これはサティアなの?それともこのコメントの背景を知る必要があるの?

それ、あんまり意味ないよね。プロジェクトが効率悪くゼロから実装することもあるけど、再実装する代わりに使えるライブラリが他にあるかもしれないし。

プロジェクト全体がめっちゃ読みやすいのが大好き!

Rustがこんなに読みやすいとは思わなかった。なんか他のRustエンジニアたちが自己満足のためにマゾヒスティックなコンテストにハマってる気がする。それがRustコミュニティやリクルーティングに関する他のことを説明してるのかも。

かなり手続き的というか、オブジェクト指向だね。これは良いRustのプラクティスとは言えないよ。イテレーターを使うともっと関数型っぽくなって、簡潔になるし、列挙型も代数的になる。まあ、思考実験としては全然問題ないけどね。

これはAI生成だよ。

どこでトレーニングデータを手に入れたのか気になるな。自分でも調べるけど、これを見て聞いてみたくなった。分類データセットでめっちゃうまくいくCPUファーストのバックプロップなしアーキテクチャがあるんだ。連続学習に役立つかもしれない単一例のインクリメンタルアップデートができるんだ。tiny.txtでトレーニングするためのデモを作ったけど、次の文字を予測できるんだ。ただ、LLMを作ったことはないんだ。自分のアーキテクチャはデバイス上のアシスタントやオンプレミスのニーズにうまく働くかもしれないけど、恥をかく前にもっと試してみたいんだ。おすすめのオープンソースのLLMトレーニングデータセットってある?

huggingfaceにはオープンAIやAnthropicのユーザーからアシスタントチェーンがたくさんあるよ。ただ、ドラゴン(幻覚)に注意してね。でも、指示トレーニングには十分だと思う。実は、指示に従う能力のためにkimi k2を蒸留することをおすすめするよ。

https://huggingface.co/datasets/NousResearch/Hermes-3-Datase...

いいね。それにライセンスを付けてくれる?

ライセンス追加したよ!いい指摘だね。

モデルを動かすためにPythonの依存関係地獄と戦った日々を過ごした者としては、シンプルにcargo runできるのは夢みたいだよ。でも、フレームワークがないことで一番痛かったのは何だったのかな?デバッグのバックプロパゲーションロジックだったと賭けるよ、コーヒー代をかけて。

こっそり言うけど、cargoを褒める人たちは依存関係管理のトレードオフについて全然わかってない気がする。依存関係を含める難しさは、リスクに比例すべきだと思う。つまり、Cみたいに同じ5つのユーティリティを毎回再発明してるような難しさにはならないはず。でも、npmやcargoみたいに簡単すぎるのも良くない。依存関係がめちゃくちゃになって、セキュリティやビルド時間などの関連問題が出てくるからね。ビルドシステムが優れていることと、依存関係を簡単に含めることは同じじゃないし、現代の言語は一貫したビルドシステムを持つべきだと思う。誰でも自由に引っ張ったり引っ込めたりできる中央集権的なパッケージリポジトリがあって、依存関係が他の依存関係を自由に持つのは、依存関係の扱いとしては良くないよ。

GPUとかのリソース利用かな。

uv試したことある?俺にはPythonプロジェクトの痛みが90%減ったよ。

Pythonの依存関係地獄に数日間格闘してた。2010年ならそのコメントは理解できたけど、2025年にはありえないよね。

「シンプルなcargo runは夢のようだ」って、冬にCPUを温めながらインターネット全体を再コンパイルするcargo buildの方がいいの?

これやったよ [0](RustでのGPT)、jaykmodyの素晴らしいブログを参考にしてね [1]。 [0]: https://github.com/enricozb/picogpt-rust [1]: https://jaykmody.com/blog/gpt-from-scratch/

いいね!削除できるGPTのコメントがいくつか見える // より良い学習のために増やしたけど、これじゃ何も教えてくれない // lib.rsから定数を使おう const MAX_SEQ_LEN: usize = 80; const EMBEDDING_DIM: usize = 128; const HIDDEN_DIM: usize = 256; これらはlib.rsで既に定義されてるのに、なんで使わないの?(コメントが示唆してる通りに)

ああ、俺はこれを自分のハードウェアで動かしてるよ。「ゼロから」ってタイトルにあるのがポイント高い。未来は最悪だね。

定数の件、著者がどうやってやるか知らなかった可能性もあるよね。俺もRust始めたばっかの時、名前付けが全然わからなくて、考えすぎてたなぁ。

バイブコーディングされたRustが、言語のコードの質を悪くすると思う?

これ、PRとして追加したの?

それは残しておくべきだよ。実際に理解して作ったわけじゃないってことを示してるから。

ここに作者のコメントがあるよ:

おめでとう!LLMにはちょっとした問題があって、トランスフォーマーブロックを再利用してるから、別のインスタンスを使いたいんだよね。これはすごく面白い練習だよ。俺も前にZigとMLXで同じことやったから、いい基盤ができたんだけど、その後ハマっちゃって色々追加して、Pytorch/Transformersに切り替えたんだ。

修正:自分で書いたら面白い練習になるけど、GPTを使うのはダメだね。

いいね!次に追加するべきは数値勾配テストだね。

それって、部分導関数を単一のパラメータの値の小さな変化に対する損失の差で近似するってこと?結果を確認するにはいい方法だけど、前向きモードの自動微分と似たようなやり方だから、同じ欠点があるよね。