ホームGPUでLLMのファインチューニングをするとき、処理速度の壁にぶつかることがある。

2026年5月6日、オープンソースのLLM訓練ツール「Unsloth」がNVIDIAと共同研究を行い、LLM訓練を合計約25%高速化する3つの最適化手法を公開した。新しいカーネルは一切作らず、「グルーコード」と呼ばれる処理の隙間を塞ぐことで達成している。

この記事でわかること:

  • なぜ主要カーネルを最適化しても速度が頭打ちになるのか
  • パックシーケンスのメタデータキャッシュが前向き計算を最大43%高速化する仕組み
  • ダブルバッファでコピーと計算の待ち時間をなくす方法
  • MoEルーティングでCPU-GPU同期を削減する改善点

https://unsloth.ai/blog/nvidia-collab

高速化の余地はカーネルの「外側」にある

LLMのファインチューニングを高速化しようとすると、まず行列積やアテンション、MoEのルーティングといった主要カーネルに手が入る。これらが訓練全体の大半を占めるからだ。

ただし、主要カーネルが最適化されると状況が変わる。それ以外の「グルーコード」——メタデータの再構築、コピーと計算の直列実行、バッチごとのCPU-GPU同期——がステップ時間の目立つ割合を占めはじめる。

Unslothは今回、この「隠れたボトルネック」を3つ特定して修正した。

最適化1:パックシーケンスのメタデータキャッシュ

パディングを省いてシーケンスを詰め込む「パックトレーニング」では、各シーケンスの境界情報(cu_seqlens、シーケンス長、アテンションマスク構造)をバッチとともに保持する必要がある。

問題は、この情報がバッチ内では変化しないにもかかわらず、トランスフォーマーのすべての層で再構築されていたことだ。モデルにL層あれば、同じ情報がL回生成される。特にSDPAのマスク構築はGPU-CPU同期を引き起こすため、層ごとに繰り返されるとオーバーヘッドが蓄積する。

修正は「バッチごとに1回だけ計算して、すべての層で使い回す」だけだ。

実測結果(Qwen3-14B QLoRA SFT)は前向き計算で+43.3%、後ろ向き計算で+5.8%、バッチあたりで+14.3%の改善となった。前向き計算での効果が大きいのは、同じパックドメタデータを層ごとに参照する処理が集中しているからだ。後ろ向き計算では同じ量の時間が節約されても、グラジェントチェックポイントの処理が入るため相対的な改善幅は小さくなる。

なお、パックトレーニング自体がパディングを排除してGPU利用率を高める手法なので、この最適化はその効果をさらに引き出す形になる。

最適化2:ダブルバッファによるチェックポイントリロード

グラジェントチェックポイントはVRAM使用量を抑える定番技術で、中間活性化を保持せず必要時に再計算する。Unslothの実装では一部の活性化をピンドCPUメモリに退避させ、後ろ向き計算時にGPUへ転送する。

問題は転送と計算の直列実行だ。1つのバッファを使いまわすと、「CPUからGPUへコピー → 完了を待つ → 後ろ向き計算 → 次のコピー開始」という順序になる。GPUがコピーの完了を待つ時間が丸ごとオーバーヘッドになる。

ダブルバッファはこの待ち時間を隠す。バッファAで後ろ向き計算を実行している間に、バッファBへ次の活性化をコピーする。コピーと計算が並列で走るため、片方の完了を待つ必要がなくなる。

実測結果はステップあたりで8Bモデルが+8.4%、14Bモデルが+6.7%、32Bモデルが+4.6%だった。モデルが大きいほど活性化データ量が増えるため、コピーを隠す価値が高まる傾向がある。ただし32Bでは後ろ向き計算自体も重くなるため、相対的な改善幅は14Bより小さくなっている。

最適化3:MoEルーティングのargsort/bincount化

Mixture of Experts(MoE)モデルでは、各トークンをどのエキスパートへ送るかを決めるルーティング処理が入る。修正前のPyTorch実装では、エキスパートごとにtorch.whereで担当トークンを検索していた。このパターンの問題は、エキスパート数だけCPU-GPU間の動的な問い合わせが走ることだ。バッチごとにルーティング結果が変わるため、出力サイズをランタイムが確認するコストが積み重なる。

修正後はトークンをargsortで一括ソートし、bincountでエキスパートごとのオフセットを1回だけ計算する。個別エキスパートへのアクセスはそのオフセットからスライスするだけになり、動的問い合わせが大幅に減る。

ターゲットパスでは前向き計算+23%、後ろ向き計算+13%の効果が確認された。GPT-OSS構成でのチーム全体の検証では10〜15%の速度向上となっている。この最適化はnative_torchバックエンドを使うすべてのMoEモデルに適用できる。

3つの改善に共通するパターン

手法は異なるが、3つとも同じ問題を解いている。同じ情報を毎回再構築していた処理は1回だけ計算してキャッシュし、コピーと計算の直列実行はバッファを2つにして並列化し、エキスパートごとの動的問い合わせは一括処理に置き換えた。

Unslothは「主要カーネルが速くなるほど、それ以外の処理が相対的に大きくなる」と述べている。速い部分をさらに速くするより、隙間の遅い部分を削るほうが効果的になる段階がある。

これらの最適化はUnslothのオープンソースリポジトリ(GitHub: unslothai/unsloth、スター数63,000超)にすでに取り込まれており、RTXラップトップからDGX Sparkまで幅広いNVIDIA GPUで動作する。ローカル環境でLLMのファインチューニングを行っているなら、アップデートするだけで恩恵を受けられる。