この記事の要点
- 4bit 量子化済みの同じ重みを読み、シーケンス長 2048・バッチ 1・LoRA rank 16 で回すという条件を揃えてツールを替えると、8B の QLoRA でピーク VRAM が 8.30 GiB(Unsloth)/10.55 GiB(LLaMA-Factory)/11.11 GiB(素の TRL+peft)と 2.81 GiB 開いた(Windows での実測。勾配チェックポイントの実装など、方式に固有の部分は揃えていない)。
- 今回の同世代・同容量の 2 枚では、カードを替えてもピーク VRAM はほぼ変わらず、ツールでだけ動いた。速度は両方が効くが効き幅が違い、カードで約 2.1 倍、ツールでは 1.24〜1.28 倍。ただし画面出力にも使っているカードで容量を使い切った条件では、この規則性が崩れた。
- Unsloth の VRAM 優位は、一部が中間活性をシステム RAM へ逃がすことで成立している(公式ドキュメントは「さらに 30% 削減・時間コスト +1.9%」を記載している)。必要な量が減ったのではなく、置き場所が移っている。
- Windows ネイティブでは Axolotl を通常の pip 依存解決で導入できなかった(依存の triton に Windows 向け配布がない。公式は WSL2 か Docker を案内)。LLaMA-Factory は今回の環境で torch が CPU 版に置き換わった。
- 選び方の目安:16GB で大きめのモデルまで狙うなら Unsloth、設定ファイルで多数のレシピを管理したいなら LLaMA-Factory、学習ループを自分で書きたいなら素の TRL。Windows ネイティブのまま通常の pip で入れる前提なら、Axolotl は導入の時点で候補から外れる。
ローカルの GPU で LLM に追加学習をかけると決めたあと、次に決めるのは「どのツールで回すか」になる。Unsloth、LLaMA-Factory、Hugging Face の TRL を直接叩く方法、そして Axolotl。どれも QLoRA を回せると書かれていて、必要 VRAM も速度も「ツールを選べば下がる」と説明されている。
もっとも、公開されている数字は条件つきのものが多い。Unsloth の「約2倍・VRAM 70%以上削減」にも、比較基準とバッチ構成・LoRA rank という前提がある。手元の条件がそれと違えば、出てくる数字も変わる。16GB のカードで「残り何 GiB あるのか」を読むには、自分の条件で測るしかない。
そこで、モデルの重み・データ・ハイパーパラメータを固定し、ツールを入れ替えて測った。なお Axolotl は Windows ネイティブへの通常の pip 導入ができなかったため(理由は記事後半で扱う)、実測は Unsloth・LLaMA-Factory・素の TRL の 3 方式で行っている。
同じ学習を回しても、ツールが違うと VRAM は 2.8 GiB 変わる
先に結論から。llama-3-8B を 4bit の QLoRA で、シーケンス長 2048・バッチ 1 で学習させたときのピーク VRAM は次のようになった。
| 方式 | ピーク VRAM | カード容量との差分(PyTorch 予約量基準・参考値) |
|---|---|---|
| Unsloth | 8.30 GiB | 7.62 GiB |
| LLaMA-Factory | 10.55 GiB | 5.37 GiB |
| 素の TRL + peft | 11.11 GiB | 4.81 GiB |
8B クラスなら 16GB のカードにはどれでも収まる。差が表に出てくるのは、シーケンス長を伸ばしたい、バッチを 2 にしたい、もう少し大きいモデルに手を伸ばしたい、といった場面になる。
測り方|条件をどこまで揃え、どこが揃っていないか
ツール比較でいちばん壊れやすいのは、比較しているつもりで別のものを比べてしまうところにある。学習率が違う、LoRA を当てるモジュールが違う、といった差はすべて VRAM と速度に出る。
今回、次は全条件で共通にした。
- モデルの重み:
unsloth/llama-3-8b-bnb-4bit(3方式とも同一のチェックポイント。4bit 量子化済みのものをそのまま読む) - データ:シーケンス長 2048 を確実に埋める合成テキスト
- LoRA 構成:rank 16 / alpha 32 / 対象は
q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_projの 7 モジュール - ハイパーパラメータ:学習率 2e-4 / オプティマイザ adamw_8bit / packing なし(勾配チェックポイントは 3 方式とも有効。ただし実装が違うので後述)
- PyTorch:2.10.0+cu128
LoRA の当たり方が本当に同じかは、学習対象パラメータで確認できる。実測では 8B が 3 方式とも 41,943,040、14B が 3 方式とも 65,536,000 で一致した。総数だけでは当て方のずれを見逃しうるため、学習対象テンソルの名前と形状まで書き出して突き合わせたところ、3 方式とも 8B が 448 個・14B が 560 個で完全に一致した(model.layers.0.mlp.down_proj.lora_A.weight [16, 14336] のような単位で全件一致)。
一方で、これは単一の変数だけを入れ替えた比較ではない。揃っていない部分を先に挙げておく。
- 勾配チェックポイントの実装が違う。Unsloth は
use_gradient_checkpointing="unsloth"(中間活性をシステム RAM へ逃がす独自モード)、素の TRL と LLaMA-Factory は transformers 標準の実装を有効化している。これは Unsloth の中心的な機能なので外すと「Unsloth を使った」ことにならないが、差の一因ではある。 - 学習ループが違う。Unsloth と素の TRL は TRL の
SFTTrainer、LLaMA-Factory は自前の Trainer(transformers のSeq2SeqTrainer派生)を使う。 - LLaMA-Factory だけライブラリのバージョンが違う。torch 置換の都合で別の仮想環境に入れており、transformers と peft の版が他の 2 方式と異なる。
- LLaMA-Factory はチャットテンプレートを適用する。
つまり以下の差は「それぞれを標準的な使い方で組んだときの方式ごとの差」であって、ロード層だけを厳密に入れ替えた差ではない。
VRAM は PyTorch の max_memory_reserved のピークを、学習ループに入った時点でカウンタをリセットしてから取っている。ステップ時間は暖機 2 ステップを除いた中央値。ここでいう 1 ステップはオプティマイザ更新 1 回ぶんで、本文の測定はすべて勾配累積 1(=forward / backward 1 回)で揃えている。各条件は 1 回の学習ラン(8B の 1 枚構成は最大 12 ステップ、14B と 2 枚構成は最大 10 ステップ)による測定で、複数回平均や信頼区間は取っていない。時間は CUDA イベントによる同期計測ではなく学習ループ側の実時間で測っているため、小数第 2 位までがそのまま再現するとは限らない。
| 項目 | 内容 |
|---|---|
| GPU(主) | RTX 5080 16GB(実容量 15.92 GiB・画面出力に使用) |
| GPU(比較) | RTX 5060 Ti 16GB(OCuLink 外付け・画面出力なし) |
| CPU / RAM | Core i7-14700F / 96GB |
| OS | Windows 11 |
| ライブラリ(Unsloth / 素の TRL) | Unsloth 2026.6.9 / TRL 0.24.0 / transformers 5.5.0 / peft 0.19.1 / bitsandbytes 0.49.2 |
| ライブラリ(LLaMA-Factory) | LLaMA-Factory 0.9.5 / transformers 5.6.0 / peft 0.18.1 / bitsandbytes 0.49.2(別の仮想環境。PyTorch は揃えたが transformers と peft は版が異なる) |
8B で測る|VRAM を動かすのはツール、速度を大きく動かすのはカード
同じ 8B の学習を、RTX 5080 と RTX 5060 Ti のそれぞれ 1 枚で回した結果が次になる。
| 方式 | ピーク VRAM | RTX 5080 | RTX 5060 Ti |
|---|---|---|---|
| Unsloth | 8.30 GiB | 2.18 秒/step | 4.50 秒/step |
| LLaMA-Factory | 10.55 GiB | 2.40 秒/step | 5.04 秒/step |
| 素の TRL + peft | 11.11 GiB | 2.71 秒/step | 5.75 秒/step |
この表には 2 つの軸が入っていて、効き幅が違う。
ツールを替えると VRAM が大きく動き、速度も 1.24 倍ぶん動く。VRAM は 8.30 から 11.11 GiB まで 2.81 GiB、割合にして 25.3% 開いた。速度差はそれより小さい。
今回の 2 枚では、カードを替えても VRAM は動かず、速度だけが約 2.1 倍動いた。ピーク VRAM は 5080 で測っても 5060 Ti で測っても同じ値になる(同世代・同容量どうしの比較であって、世代やドライバ、画面出力の有無が変われば差が出る可能性はある)。一方の速度比は Unsloth で 2.06 倍、LLaMA-Factory で 2.10 倍、素の TRL で 2.12 倍と、どのツールでもほぼ揃った。
効き幅を並べると、カードで 2.1 倍、ツールで 1.24 倍。16GB に載るかどうかで困っているならツールを見直す。学習が終わるまでの時間で困っているならカードを見る。逆に、モデルと設定が同じなら、同じ 16GB の別のカードへ替えるだけでは必要な PyTorch 予約量は基本的に変わらない。画面出力の有無やドライバによる実際の空き容量の差は、それとは別の話になる。
この規則性が成立するのは、どちらのカードにも余裕がある範囲に限られる。14B では、画面出力に使っている 5080 側で容量を使い切った条件で崩れた。
Unsloth の VRAM 優位には内訳がある
Unsloth の勾配チェックポイント(今回指定した use_gradient_checkpointing="unsloth")は、中間活性をシステム RAM 側へ非同期に逃がす実装になっている。Unsloth 公式の解説はこの仕組みで「さらに 30% のメモリ削減」「時間コストは +1.9%」を記載している。つまり Unsloth の差の一部は「必要な量が減った」ではなく「置き場所を GPU からメインメモリへ移した」ことによる。今回の検証機はシステム RAM 96GB でここが詰まらなかったが、メインメモリの少ない構成では同じようには効かない(推論・画像生成側での実測はローカル AI にシステム RAM は何 GB 必要かで扱っている)。
14B で測る|差が「余裕」から「あと 1.75 GiB」に変わる
8B では 3 方式のどれでも収まった。モデルを phi-4(14B)に上げると、同じ差が別の意味を持ちはじめる。
| 方式 | ピーク VRAM | カード容量との差分(参考値) | RTX 5080 | RTX 5060 Ti |
|---|---|---|---|---|
| Unsloth | 12.27 GiB | 3.65 GiB | 3.57 秒/step | 7.71 秒/step |
| LLaMA-Factory | 13.80 GiB | 2.12 GiB | 3.88 秒/step | 8.56 秒/step |
| 素の TRL + peft | 14.17 GiB | 1.75 GiB | 5.86 秒/step | 9.62 秒/step |
3 方式とも今回の条件では最後まで走りきった。ただし差分 3.65 GiB と 1.75 GiB では性質が違う。学習データに長い例が混ざる、シーケンス長を上げる、バッチを 2 にする——どれも数 GiB 単位で消費するので、差分 1.75 GiB は次の一手がほぼ打てない状態になる。ここで詰まるなら、中古 RTX 3090 24GB はローカル AI に買いかで扱った 24GB 級へ移るという選択肢も出てくる。しかも画面出力に使っているカードなら、そこからさらに 1.3〜2.8 GB 少ない。
実際、素の TRL で 14B を RTX 5080 に載せたときは、nvidia-smi の実測が 15,815 / 16,303 MiB(97%)まで埋まり、ステップ時間が 5.14〜6.19 秒(中央値 5.86 秒に対して -12%/+6%)とばらついた。しかもばらつきだけの話ではなく、中央値そのものが他 2 方式のカード間比から期待される 4.45 秒に対して 5.86 秒と、常時 3 割ほど遅い。同じ構成を画面出力に使っていない RTX 5060 Ti で回すと 9.61〜9.63 秒(±0.1%)で微動だにしない。
この条件では、8B で見えていた規則性も崩れる。カード間の速度比は Unsloth 2.16 倍・LLaMA-Factory 2.21 倍に対し、素の TRL だけ 1.64 倍まで落ちた。異常が出ているのは 5080 側の測定だと切り分けられる——同じカードの中でツール間の比を見ると、5060 Ti では 8B 1.28 倍・14B 1.25 倍と安定しているのに、5080 では 8B 1.24 倍・14B 1.64 倍と 14B でだけ跳ねているためだ。
異常が 5080 側の測定に局在していることまでは言えるが、その原因は 1 つに絞れていない。切り分けの内訳は次のとおり。
ばらつきと、VRAM があふれることは別
Windows / WDDM 環境では、条件によっては VRAM 不足時に共有 GPU メモリとしてシステム RAM が使われ、エラーで止まらないまま大幅に低速化する場合がある。ただし CUDA の通常の OOM も起きるため、超過すれば必ず退避するわけではない。割り当て方式・ドライバ・設定・処理内容による。
今回の 14B・素 TRL で見えた約 1 割のばらつきは、別条件で観測した十数倍の低速化(FAQ で扱うバッチ 2・勾配累積 4 の条件で、オプティマイザ更新 1 回あたり 35 秒から 587 秒へ)とは規模が違う。nvidia-smi の値は 15,815 / 16,303 MiB と物理 VRAM 内に収まっていたが、これだけで共有メモリの使用を否定することはできない(確認には専用 GPU メモリと共有 GPU メモリを分けて記録する必要があり、今回は取っていない)。
ばらつきの幅(-12%/+6%)だけでは差の説明も足りない。他ツールと同じ 2.16 倍なら 4.45 秒のはずのところ中央値は 5.86 秒で、ばらつきを超える差が常時乗っている。画面表示との取り合いに加えて、97% まで埋まった状態でのメモリ確保の挙動なども考えられるが、表示を切った対照測定を取っていないため特定できない。
Unsloth の公称値は、どういう条件で出た数字か
Unsloth 公式のベンチマークページは、Llama 3.1 8B で「2倍高速」「VRAM 70%以上削減」としている。ここで重要なのは、その数字が何と比べた値なのかになる。
| 項目 | Unsloth 公式の条件 | 今回の実測条件 |
|---|---|---|
| 比較の基準 | Hugging Face + Flash Attention 2 | 素の TRL + peft(FA2 は明示的に有効化せず) |
| バッチサイズ | 2 | 1 |
| 勾配累積 | 4 | 1 |
| LoRA rank | 32 | 16 |
| 対象モジュール | 全線形層(q, k, v, o, gate, up, down) | 同じ 7 モジュール |
| GPU | H100 / Blackwell(ベンチマーク全体の記載で、8B 行ごとの指定はない) | RTX 5080 / RTX 5060 Ti(Blackwell) |
基準も、1 度に処理するバッチサイズも、LoRA rank も違う。この 2 つは単純に比較できない。そのうえで、今回の条件で出た値は次になる。
| 指標 | 実測(8B) | 実測(14B) |
|---|---|---|
| VRAM 削減率 | 25.3% | 13.4% |
| 速度(RTX 5080) | 1.24 倍 | 1.64 倍 ※ |
| 速度(RTX 5060 Ti) | 1.28 倍 | 1.25 倍 |
Unsloth が速く、VRAM も少ないことは一貫して再現した。3 方式の中では明確に最も軽い。ただし余裕のある条件での倍率は 1.24〜1.28 倍、VRAM 削減は 13.4〜25.3% にとどまる。
公称値との開きを 1 つの要因に帰属させることはできない。ピーク VRAM に効くのは主に、1 度に処理するバッチサイズ(公式 2・今回 1)、LoRA rank(32 対 16)、比較の基準(Hugging Face + FA2 か、素の TRL か)、そしてカーネルや勾配チェックポイントの実装とライブラリ版の違いになる。ただしこれらが同じ向きに効くとは限らず、どれがどれだけ寄与したのかを今回の測定から分けることはできない。
勾配累積は、バッチサイズのようにはピーク VRAM を増やさない
公式条件の勾配累積 4 を「有効バッチが 8 倍」と読んでピーク VRAM の差に結びつけるのは誤りになる。勾配累積は小さなミニバッチを順番に forward / backward し、勾配だけを足していく仕組みで、4 回分の中間活性を同時に持つわけではない。ピークに効くのは 1 度に処理するバッチサイズのほうで、公式は 2、今回は 1 だった。
実務上の意味は単純で、公称の削減率をそのまま自分の見積もりに使わないほうがよいということになる。手元の GPU でローカル LLM をファインチューニングできるかでも公称の削減率を上限として扱うべき点に触れているが、今回の実測はその見立てに具体的な数字を与える結果になった。
2 枚目の GPU は学習のどこに効くか
2 枚目のカードがあるなら学習にも使いたくなる。ここは Windows では前提が 1 つ崩れている。GPU を 1 枚で運用する場合、この章は次の「Windows で導入できるか」まで読み飛ばして差し支えない。
複数 GPU に学習を分散させる定番の FSDP や DeepSpeed は GPU 間通信に NCCL を使うが、Windows の PyTorch では NCCL が利用できない(実測でも is_nccl_available() は False)。つまり NCCL を前提とする一般的な CUDA マルチ GPU 構成は、Windows ネイティブでは利用できない。標準バックエンドとしては Gloo が残るが、CUDA 向けの通信は NCCL ほど最適化されていないとされており、今回の構成では検証していない。
以下は非推奨の構成による実験である
ここで使った device_map="auto" は、Hugging Face の公式ドキュメントでは推論向けの機能(Big Model Inference)として説明されており、量子化モデルの学習では device_map を指定する必要はないとされている。以下は、公式に推奨されたマルチ GPU 学習の手順ではなく、それを学習に流用した場合の測定になる。層の配置や挙動の再現性は保証されない。
データ並列の側が塞がると、残るのは層をカードに分けて置くモデル並列になる。そのうえで、層を 2 枚に分けて置いた結果が次になる。
| 構成 | ピーク VRAM | 速度 |
|---|---|---|
| 素の TRL・RTX 5080 単体 | 11.11 GiB | 2.71 秒/step |
| 素の TRL・2 枚モデル並列 | 合計 14.07 GiB(5080 側 4.51 / 5060 Ti 側 9.56) | 5.44 秒/step |
| Unsloth・2 枚指定 | 合計 8.32 GiB(5060 Ti 側 0.02) | 2.22 秒/step |
2 枚に分けても動きはするが、1 枚で回すより約 2 倍遅くなった。
今回のように層を順番に通していく方式では、2 枚あっても計算が重ならないため速くはならない(マイクロバッチを使って複数 GPU の計算を重ねるパイプライン並列は別の方式で、今回は使っていない)。そのうえ 32 層のうち 28 層が遅いほうの RTX 5060 Ti に載った。5060 Ti は同じ学習で 2.12 倍遅いので、層の配分だけで概算すると 4/32 × 2.71 + 28/32 × 2.71 × 2.12 = 約 5.4 秒。実測の 5.44 秒とほぼ一致する。遅くなった主因が「大半の層が遅いカードで動いたこと」だという見方と整合する結果になる。
もっとも、これは合計値が 1 つ合っただけで、GPU 間の転送時間を分離して測ったわけではない。層ごとの演算量や同期・転送量を別に測らないと、内訳までは確定できない。
層の配分も直感に反する。device_map="auto" は本来おおむね均等に分けるはずだが、実際には 32 層のうち 28 層(パラメータテンソルで 739 個中 646 個、確保された VRAM で 4.51 GiB 対 9.56 GiB)が OCuLink 側の RTX 5060 Ti に載った。測定開始時点の占有は 5080 側が約 1.3 GB・5060 Ti 側が 0 で、この差だけでは説明が付かない配分になっている。4bit 量子化したモデルで配置が偏る事例は報告もあり、原因は今回のデータからは特定できない。いずれにせよ、置き場所を任せると速いカードのほうが空く場合がある。
Unsloth については、2 枚を指定しても RTX 5060 Ti 側の予約は 0.02 GiB にとどまり、実質 1 枚で走った。速度も単体(2.18 秒)とほぼ同じ 2.22 秒だった。
今回の device_map="auto" による逐次的な層分割では、2 枚目を足しても学習は速くならなかった。ここは実測で数字が付いた。DDP・FSDP・パイプライン並列といった最適化された分散学習まで含めて「2 枚では速くならない」と言えるわけではない。残るのは「1 枚に載らないモデルを分けて載せる」用途だが、今回 2 枚で回したのは 1 枚に載る 8B までなので、そこは測れていない。推論側での 2 枚の挙動はローカル LLM を 2 枚の GPU の VRAM プールで動かすとAI 用途に GPU は 2 枚必要かで扱っている。
Windows で導入できるか|Axolotl は入らず、LLaMA-Factory は torch を差し替える
性能以前に、導入の段階で選択肢が減る。
Axolotl は Windows ネイティブでは pip 導入できなかった
Axolotl は依存関係の解決に失敗して導入できなかった。原因は triton で、pip が試したすべてのバージョンの Axolotl がこれを要求する一方、triton には Windows 向けの配布が存在しない。Windows では triton-windows という別名のフォークを使うが、パッケージ名が違うため依存条件を満たせず、ResolutionImpossible で止まる。公式のインストール手順も Windows では WSL2 または Docker を案内しているため、そちらに移すなら選択肢に入る。Windows ネイティブのまま、通常の pip による依存解決で入れる前提では検討対象から外れる。
今回の Windows 環境では、通常の pip 導入で torch が CPU 版に置き換わった
LLaMA-Factory は導入自体は成功する。ただし今回の環境で pip install llamafactory を実行したところ、導入済みの CUDA 対応 torch がアンインストールされ、CPU 版に置き換わった。公式の Windows 向け手順でも GPU 版 PyTorch を手動で導入するよう案内されている。置換後は torch.cuda.is_available() が False、対応アーキテクチャの一覧も空で、GPU が完全に見えない状態になる。気づかずに学習を始めると CPU で回ることになる。
回避策は 2 つある。1 つは専用の仮想環境に入れること。既存の環境に入れると、動いていた他のツールごと巻き込まれる。もう 1 つは導入後に CUDA 対応の torch を入れ直すこと。今回は LLaMA-Factory 側の要求が torch>=2.4.0 と緩かったため、他の 2 方式と同じ版に戻せた。
あわせて、4bit 量子化に必要な bitsandbytes は別途入れる必要がある。0.9.5 のパッケージ情報を確認したところ、bitsandbytes は依存にも追加指定(extra)にも含まれていない。
Unsloth 向けの記事どおりに書くと素の TRL では動かない
もう 1 つ、解説を写して動かすときに引っかかる点がある。Unsloth は読み込み時に TRL 側へパッチを当てており、そのパッチが古い引数名を生かしている。SFTConfig(max_seq_length=...) や SFTTrainer(tokenizer=...) は Unsloth を使っていれば通るが、素の TRL 0.24 ではそれぞれ max_length、processing_class に変わっており、そのままでは例外で止まる。Unsloth を前提に書かれた手順を素の TRL に持っていくときは、この差を踏むことになる。
どれを選ぶか
| 状況 | 向く方式 | 理由 |
|---|---|---|
| 16GB で 14B クラスまで狙いたい | Unsloth | 3 方式で最も軽く、カード容量との差分が 3.65 GiB あり、3 方式で最も余裕がある(画面出力に使うカードなら実効はさらに小さい) |
| 同じカードで少しでも速く回したい | Unsloth | 同条件で 1.24〜1.28 倍。ただしカードを替えるほどの差ではない |
| 設定ファイルで多数のレシピを回したい | LLaMA-Factory | VRAM・速度とも中間。導入時の torch 置換に対処する手間が要る |
| 自分で学習ループを書きたい/依存を最小にしたい | 素の TRL + peft | 最も重く最も遅いが、挙動が読みやすく他ライブラリと組み合わせやすい |
| システム RAM が少ない | Unsloth の優位は縮む可能性 | VRAM 削減の一部が活性のメインメモリ退避で成立しているため |
| Windows のまま使いたい | Axolotl は対象外 | 通常の pip の依存解決では triton を満たせず導入できない(triton-windows への差し替えや WSL2 / Docker 経由は未検証) |
なお学習を長時間まわすなら、発熱と電力の設計も別途効いてくる(AI 用 PC の冷却とケースの選び方)。8B クラスに限れば、どの方式でも 16GB に収まって数秒/step で回る。ツール選びが表に出てくるのは、モデルを 14B に上げる、シーケンス長を伸ばす、バッチを増やす、といった形で容量を使い切りにいくときになる。
よくある質問
Unsloth が最も軽いなら、他を選ぶ理由はあるか
今回測った 3 方式のうち、VRAM と速度だけを見れば Unsloth が有利だった。ただし Unsloth は独自のパッチをライブラリ群に当てるため、他の学習ライブラリと組み合わせたい場合や、学習ループ自体を書き換えたい場合には扱いにくくなる。VRAM 削減の一部が活性のメインメモリ退避で成立している点も、システム RAM の少ない構成では前提が変わる。設定をファイルで管理して多数の条件を回すなら LLaMA-Factory、挙動を完全に把握したいなら素の TRL、という分かれ方になる。
ピーク VRAM がカードによらずほぼ同じなのはなぜか
4bit に量子化した重み、LoRA アダプタ、オプティマイザ状態、勾配チェックポイント後の中間活性——学習中に確保されるものは、モデルと設定が同じであればカードが変わっても変わらないため。カードが変えるのは計算の速さであって、必要な容量ではない——少なくとも今回のように同世代・同容量どうしを比べる限りは。世代やドライバが変わればカーネルや作業領域の取り方も変わるため、同じとは限らない。ただし空き容量がそれを下回れば話は別で、その場合は載らないか、Windows なら共有メモリへ退避して極端に遅くなる。なお測定はアロケータが確保した量のピークなので、確保単位のぶれで小数第 2 位はわずかに動く。
RTX 5060 Ti が遅いのは OCuLink 接続だからか
まず、この 2 枚はカタログ上の素の性能がそれだけ違う。NVIDIA 公式のスペックを並べると次になる。
| 公称スペック | RTX 5080 | RTX 5060 Ti | 比 |
|---|---|---|---|
| CUDA コア数 | 10,752 | 4,608 | 2.33 倍 |
| ブーストクロック | 2.62 GHz | 2.57 GHz | 1.02 倍 |
| メモリバス幅 | 256-bit | 128-bit | 2.00 倍 |
結論から言えば、今回の 2.06〜2.12 倍という実測差には、カード本体の性能差が大きく寄与していると考えられる。コア数もメモリインターフェース幅も大きく違う。一般的な単一 GPU 学習では、重みやオプティマイザ状態の多くが GPU 上に保持されるため、すべてをステップごとに CPU との間で往復させるわけではない。実際、毎ステップの CPU 退避を伴うのは 3 方式のうち Unsloth だけだが、GPU 上で再計算する標準の勾配チェックポイントを使う LLaMA-Factory と素の TRL でも比は 2.10 倍・2.12 倍で揃っている。
一方で限界もある。Unsloth の勾配チェックポイントは中間活性をシステム RAM へ逃がすため、OCuLink を含む CPU ― GPU 間の通信がステップごとに発生する。その通信が速度に与えた影響は今回の測定では分離できていない(退避を行う Unsloth の比が 3 方式で最も小さい点は、リンクが支配的でないことと整合するが、直結との対照がない以上それ以上は言えない)。上の比はカタログ値どうしの比であって、Tensor Core の演算・メモリ帯域・カーネル効率が混ざる Transformer 学習で本来出るべき性能比というわけでもない。直結した RTX 5060 Ti との対照測定も行っていない。
測定として言い切れるのは、OCuLink 接続を含む実環境で、8B の 3 方式がいずれも約 2.1 倍のカード間差を示したところまでになる。
OCuLink を使っていない環境で同じ速度になるとは限らないが、5060 Ti 側の値は外付け接続を含む 1 つの実測例として参照できる。推論側を含めたこのカードの実用域はRTX 5060 Ti 16GB でどこまでできる?で扱っている。なお 2 枚のモデル並列では層の境界でデータが往復するため、そこでは条件が変わる。
バッチサイズを上げるとどう変わるか
今回はバッチ 1 で統一している。本文の計測とは別日・別ハーネスになるが、Unsloth・8B でバッチを 2 に上げ、画面出力に使っていない RTX 5060 Ti(実容量 15.93 GiB)で測ったときは、ピーク VRAM が 14.97 GiB まで上がり、エラーも極端な低速化も出ないまま最後まで走った(1 ステップ 13.08 秒。同じカード・バッチ 1 の 4.50 秒に対して約 2.9 倍で、バッチが 2 倍になった以上に伸びている)。専用 VRAM と共有 GPU メモリを分けて記録していないため、退避が皆無だったとまでは言えない。同じくバッチ 2 に勾配累積 4 を重ねた条件を、画面表示に使っている RTX 5080 で回した際は 1 ステップが 35.17 秒から 587.54 秒まで悪化した。ここでいう 1 ステップはオプティマイザ更新 1 回ぶんで、勾配累積 4 なら forward / backward 4 回を含む。本文の他の数字は勾配累積 1 なのでこの条件とは直接比較できない。16GB でバッチを上げるのは、容量の余裕を確認したうえでの判断になる。
学習の可否そのものを知りたい場合は
16GB で QLoRA・LoRA・フル微調整のどれが成立するか、必要 VRAM がどう変わるかは手元の GPU でローカル LLM をファインチューニングできるかで扱っている。本記事は「やると決めたあと、どのツールで回すか」に絞っている。
まとめ
同じモデル・同じデータ・同じ LoRA 構成で、ツールを入れ替えて測った結果、ピーク VRAM は 8B で 8.30 / 10.55 / 11.11 GiB、14B で 12.27 / 13.80 / 14.17 GiB と開いた。学習対象テンソルは 3 方式とも名前と形状まで一致しているので、この差は LoRA の当たり方の違いによるものではない。一方で勾配チェックポイントの実装、Trainer、LLaMA-Factory 側のライブラリ版とチャットテンプレートは揃っていないので、単一の変数を入れ替えた差ではなく「各方式を標準的な使い方で組んだときの差」になる。
整理すると、今回の同世代・同容量の 2 枚では、VRAM を決めるのはツール、速度を大きく決めるのはカードだった(ツールでも 1.24〜1.28 倍ぶんは動く)。ただし VRAM がほぼ埋まる条件ではこの規則性は崩れ、実際 14B・素の TRL・RTX 5080 ではカード間比が 1.64 倍まで縮んだ。
3 方式では Unsloth が最も軽い。ただしその優位は、一部が中間活性をメインメモリ側へ逃がすことで成立している。公称の「2倍・VRAM 70%以上削減」は、基準も、1 度に処理するバッチサイズも、LoRA rank も違う条件での値で、今回の条件では 1.24〜1.28 倍・13.4〜25.3% だった。公称の倍率で見積もりを立てると足りなくなる。
2 枚目の GPU は、Windows では NCCL が使えないため一般的な CUDA マルチ GPU 構成が使えない。推論向けとされる device_map="auto" で層を分けて載せる実験では、速くならないどころか 1 枚より約 2 倍遅くなった(最適化された分散学習まで含めた話ではない)。32 層のうち 28 層が遅いほうのカードに載ったことと整合する結果になる。
導入面では、Axolotl は Windows ネイティブに通常の pip では入らず、LLaMA-Factory は今回の環境で torch が CPU 版に置き換わった。性能表を見る前に、この 2 つで選択肢が絞られることのほうが先に決まる。
参考資料
- Unsloth 公式ベンチマーク(公称値とその測定条件の出典)
- Unsloth 公式: 勾配チェックポイントと活性のオフロード
- Hugging Face TRL 公式ドキュメント
- Hugging Face PEFT 公式ドキュメント
- LLaMA-Factory 公式リポジトリ
- Axolotl 公式インストール手順
- NVIDIA 公式: GeForce RTX 5080 製品仕様
- NVIDIA 公式: GeForce RTX 5060 ファミリー製品仕様
- Hugging Face Accelerate: Big Model Inference(device_map の位置づけ)
- Tim Dettmers ほか: QLoRA — Efficient Finetuning of Quantized LLMs
当サイトはAmazonアソシエイト・プログラムの参加者です。Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。

