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

Show HN: NVMe経由でCPUをバイパスして単一のRTX 3090上で動作するLlama 3.1 70B

2026年2月22日原文(github.com)

概要

NTransformer は、 高効率なC++/CUDAベースのLLM推論エンジンLlama 70BRTX 3090(24GB VRAM)単体で実行 可能。 GPUメモリを超えるモデルサイズもNVMe経由ストリーミングで対応3層アダプティブキャッシュ・レイヤースキップなど高速化技術搭載Linux・CUDA 13.1・gcc-14対応、ハードウェア設定に注意が必要

NTransformerの特徴と概要

  • NTransformer は、 C++/CUDAのみ で動作する 高効率LLM推論エンジン
  • Llama 70B のような大規模モデルを RTX 3090(24GB VRAM)1枚で実行 可能。
  • モデルレイヤーをGPUメモリにストリーミング転送 し、PCIe帯域を最大限活用。
  • NVMeダイレクトI/O により、 CPUを完全にバイパス することも可能。
  • GGUFモデル形式 に対応し、 Q4_0/Q8_0/Q4_K_M/Q5_K/Q6_K/F16/F32量子化 をサポート。

主要なベンチマーク・結果

  • 8Bモデル(Q8_0)全レイヤーVRAM常駐約49 tok/s (10GB VRAM使用)。
  • 70Bモデル(Q6_K, Q4_K_M)ティアード/ストリーミング0.2~0.5 tok/sVRAM 23GB前後で動作
    • Q4_K_M36レイヤーVRAM常駐レイヤースキップ でさらに高速化。
  • 3層アダプティブキャッシュ (VRAM常駐+ピンRAM+NVMe/mmap)で mmapベースライン比83倍高速化
  • PCIe Gen3 x8帯域(約6.5GB/s) が主なボトルネック。

高速化技術

  • 3層キャッシュ自動最適化 :VRAM常駐、ピンRAM、NVMe/mmapの3階層を自動調整。
  • SLEPストリーミング :NVMe読み出し、PCIe DMA、GPU計算をパイプラインで並列化。
  • gpu-nvme-direct :ユーザ空間からNVMeコントローラへ直接アクセスし、GPUメモリへDMA転送。
  • レイヤースキップ :コサイン類似度で冗長レイヤーをスキップ(70Bで20/80レイヤー省略可能)。
  • 自己投機的デコーディング :VRAM常駐レイヤーをドラフトモデルとして利用。

システム要件・依存関係

  • Linux(Ubuntu, kernel 6.17+推奨)
  • CUDA Toolkit 13.1
  • gcc-14 / g++-14
  • NVIDIA GPU Compute Capability 8.0+(RTX 3090動作確認済)
  • CMake 3.24+
  • (オプション)NVMe SSD(専用スロット推奨)+gpu-nvme-directライブラリ
  • 外部依存なし(PyTorchやcuBLAS不要)

ビルド・実行方法(クイックスタート)

  • ビルド例
    mkdir build && cd build
    cmake .. -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_C_COMPILER=gcc-14 \
      -DCMAKE_CXX_COMPILER=g++-14 \
      -DCMAKE_CUDA_COMPILER=/usr/local/cuda-13.1/bin/nvcc
    cmake --build . -j
    
  • 実行例(VRAM常駐)
    ./ntransformer -m /path/to/llama-8b-q8_0.gguf -p "Hello" -n 128
    
  • 実行例(ストリーミング)
    ./ntransformer -m /path/to/llama-70b-q6_k.gguf -p "Hello" -n 32 --streaming
    
  • レイヤースキップ併用(70B向け高速化)
    ./ntransformer -m /path/to/llama-70b-q4_k_m.gguf -p "Hello" -n 32 --streaming --skip-threshold 0.98
    
  • 自己投機的デコーディング
    ./ntransformer -m /path/to/llama-70b-q6_k.gguf -p "Hello" -n 32 --self-spec --draft-k 3
    
  • チャットモード
    ./ntransformer -m /path/to/model.gguf --chat
    
  • ベンチマーク
    ./ntransformer -m /path/to/model.gguf --benchmark -n 64
    

システムセットアップと安全性

  • NVMeダイレクトI/O利用にはシステムレベルの設定変更が必要
    • 自動化スクリプト(setup_system.sh) で対応。
    • IOMMU無効化、カーネルパッチ、VFIOバインド等を実施
    • 誤設定はシステム不安定化・データ損失のリスク
  • 絶対にブートドライブ(OSディスク)をNVMeダイレクトI/Oに使わないこと
  • ハードウェア損傷・データ損失の責任は自己負担

主要スクリプトと用途

  • scripts/setup_system.sh
    • 初回セットアップシステム状態確認NVMeのみ再設定 に対応。
  • scripts/setup_nvme.sh [BDF]
    • 単体NVMeのVFIOバインド
  • scripts/restore_nvme.sh [BDF]
    • NVMeをカーネルドライバに戻す

NVMeダイレクトストリーミングの仕組み

  • モデル(GGUFファイル)をNVMe生ブロックデバイスに書き込み
  • NVMeをVFIOでユーザ空間にバインドし、gpu-nvme-directで初期化
  • 推論時、各レイヤー(例:70B Q6_Kで約670MB)をNVMeから直接CUDAピンメモリへDMA転送
  • NVMe読み出し、PCIe DMA、GPU計算をダブルバッファで並列化

アーキテクチャ構成

  • src/core/ :テンソル・アロケータ・GPU管理
  • src/cuda/ :GEMV・RMSNorm・RoPE・SwiGLU・softmax CUDAカーネル
  • src/memory/ :SLEP層ストリーミングエンジン(NVMe+mmap)
  • src/model/ :Transformer構成・GGUFローダー
  • src/inference/ :トークナイザー・サンプラー・推論エンジン
  • scripts/ :システムセットアップ・NVMe管理スクリプト

3層アダプティブキャッシュ詳細

  • Tier A(VRAM常駐) :I/Oゼロ、全レイヤー常駐
  • Tier B(ピンRAM) :H2D DMAでVRAMに転送、ダブルバッファ
  • Tier C(NVMe/mmap) :NVMe直読み・メモリコピー、必要時のみ利用
  • 階層サイズはcudaMemGetInfo()/proc/meminfoから自動算出

量子化フォーマット対応表

  • Q4_0 :4.5bit/重み、32ブロック
  • Q8_0 :8.5bit/重み、32ブロック
  • Q4_K_M :4.5bit/重み、256ブロック(混合型)
  • Q5_K :5.5bit/重み、256ブロック
  • Q6_K :6.6bit/重み、256ブロック
  • F16/F32 :16/32bit/重み、1ブロック

開発ロードマップ

  • Phase 1 :8Bモデル・CUDAカーネル・高速化(完了)
  • Phase 2 :SLEPストリーミング・3層キャッシュ(完了)
  • Phase 3 :Q4_K_M/Q5_K対応・レイヤースキップ・自己投機的デコーディング(完了)
  • Phase 4 :NVMeダイレクト(GPU主導NVMe読み、3.35GB/s)
  • Phase 5 :投機的デコーディング・ベンチマーク・C API整備

技術的背景と意義

  • CPU/RAMをバイパスしGPUとNVMeを直結する発想 から誕生。
  • コンシューマGPUでも大規模LLM推論を可能にする新アプローチ
  • プロフェッショナルGPUではさらに高い性能を期待

注意:本プロジェクトはハードウェア・システムに深く関与するため、十分な知識とバックアップ体制のもとで運用してください。

Hackerたちの意見

0.2 tok/sは実験には十分だけど、実際にはインタラクティブじゃないよね。多くのユースケースでは、ちゃんと量子化された8Bや13Bモデルの方が、レイテンシとクオリティのバランスが良いと思う。

パフォーマンステーブルを見たとき、上位のモデルが8Bだってことに気づくまでよく分からなかった。5秒/トークンは確かに遅いね。これは低RAMのマシン向けなのかな?5950xに128GBのRAMがあるから、3060のGPUでいくつかのレイヤーやプリフィルを使えば、もっと速く動かせると思う。2秒/トークンで計算制約があるって言ってるけど、3090だとそれは正しくない気がする。

高品質で大きなモデルが、低レイテンシのモデルよりも好まれるシナリオがいくつか想像できるよ。特にクオリティが必要なときね。

そうなんだ、実際にこれが可能かどうか試してみたかったんだ。PS2でクラシックトランスフォーマーを使って、3000トークン/sくらい出せたんだけど、エモーションエンジンが32ビットアドレスに対応してるからね。でも、32GBのRAMがあるから、その速さの理由が気になったんだ。小さいモデルでもその速度が出せなかったのは、命令がメモリからGPUに直接行くからで、普通のコンピュータだと毎回CPUに命令をリクエストしなきゃいけないんだよね。プロ用のカードだと、そういう問題を自然に回避できるんだけど、残念ながらGPUに3万ドルも出せる余裕はないんだ :(

CPU+GPUで動かすより遅いね。7950X+3090で20480トークンのコンテキストを使うと、簡単に1.5トークン/s出せるよ。

DirectXって、アセットを直接GPUメモリにロードするためのAPIを追加したんじゃなかったっけ?それって使えるのかな?

僕の印象では、それはアセットに限られていて、DirectXフレームワークにうまくはまる必要があるみたい。見た感じ、gpu-nvme-directは主にhttps://github.com/enfiskutensykkel/ssd-gpu-dmaやhttps://github.com/ZaidQureshi/bamに似てるね。

いいね。僕も似たようなことを考えてて、VRAMの半分以下で1Tモデルを動かすことを検討してる。ある試算では、SGLangのルーティングレイヤーを修正して、Gen5 NVMeストレージからGPUメモリに直接JIT予測先のエキスパートスワップをサポートすることが理論的に可能だって言ってた。これが本当だといいな。セットアップはNVIDIA Dynamoに依存してるから、NIXLのプリミティブが使えるはず。もう誰か試した人いるのかな?

それは見てみたいね。実は、3090をもう一枚買って、マザーボードもアップグレードしようかなって考えてたんだ。PCIe3でボトルネックになってるから、GLM 4.7か5をQ4_K_Mで動かすのはできるはずなんだ。

これってマルチティアのMoEに使えるかな?例えば、アクティブなもの+VRAMで最も使われるもの、RAMでよく使われるもの、NVMeであまり使われないものとか。

そういえば、VRAMとRAM用の2ティアのMoEをトレーニングしてる人が少ないのは不思議だよね。共有エキスパートのデザインはもうあるから、「コア」エキスパートに10倍や100倍の頻度で割り当てるルーターを実装するのは難しくないはず。トレーニング中のバランス調整は難しいかもしれないけど、ルーター層にカスタムロスを使えばうまくいくと思う。ルーターが直列的一貫性を持つようにトレーニングされてないのも不思議で、数層先にVRAMにスワップするためのレイヤーを予測できるようにすれば、利用可能な帯域幅を最大化できるのに。

これは実験するには面白い分野だね。長期的には、モデルの最適化(モデルの機能に影響を与えずに省ける部分を知ること)が、圧縮アルゴリズムと同じように研究の主流になると思う。実際、モデルは損失のある圧縮方式だからね。それが進むことで、AIの民主化が進んで、作られているサイロから離れることができるのはいいことだよ。

Hacker Newsで議論の続きを見る