ブログ

Qwen3.8-Flash-Next の GGUF はどれを選ぶか——最小 4 段は「名前が違うだけ」に近い、ヘッダを読んだ実測

Unsloth の Qwen3.8-Flash-Next GGUF 11 段をテンソル表から実測。UD-IQ1_S(72.5GB)は公称 1.56 bpw、実測 3.28 bpw。最小 4 段は名前で 2 倍の差を謳いながら実測 3.28〜3.71 に収まり、体積差は 10GB 弱。128GB 機での選び方を整理します。

Linden Kern約 11 分
bartowski の Nemotron-3.5-Lightning GGUF 各ファイルについて、ファイル名が謳う bpw とテンソル表から実測した bpw を並べたダンベル図。k/i-quant の全段が 4.5 bpw の床に張り付いている

結論から。128GB のユニファイドメモリ機で Qwen3.8-Flash-Next を動かすなら、選択は UD-Q3_K_XL(90.0 GB)か UD-Q2_K_XL(78.9 GB)の二つでほぼ足ります。 その下の 4 段—— UD-IQ3_XXS 82.0 GB、UD-Q2_K_XL 78.9 GB、UD-IQ1_M 74.5 GB、UD-IQ1_S 72.5 GB——は名前の上では 3.06 から 1.56 bits per weight(bpw)まで、およそ 2 倍の幅を謳っています。ところが GGUF の ヘッダにあるテンソル表を読むと、実測は 3.71 から 3.28 bpw、幅は 1.13 倍しかありません。 体積差は 10 GB 弱です。理由は llama.cpp の量子化ツールにある tensor_type_fallback() という関数で、これは発行元の問題ではなく、ツールと新しいアーキテクチャの組み合わせが 生む挙動です。

数字は二種類に分けて書きます。当方実測は 2026-08-29 に ggufaudit 0.1.0 で Hugging Face の公開リポジトリのヘッダだけを読んだ値、自己申告は Reddit の投稿者と Unsloth の ドキュメントの値です。

まず 11 段の表:名前の bpw、実測の bpw、体積、128GB 機での可否

Zenn の tomohisa 氏の記事 (2026-08-28、M4 Max 128GB)には、Unsloth の 11 段について「重み + KV(131k)」と「128GB 機での 可否」を並べた表があります。そこに当方が実測した列を足したのが次の表です。体積は Hugging Face と Unsloth のドキュメントが示す GB 値、bpw の実測列と判定は当方の 2026-08-29 の測定です。

最後の列は品質評価ではなく、名前と中身が合っているかです。✗ は実測が公称を上回る、 ⚠ は置換はあるが平均は不変、✓ は一致。✗ は壊れても劣化してもいません——名前より 多くのビットを持つだけで、損をするのは公称値から見積もった容量です。

ファイル公称 bpw実測 bpw体積128GB 機(tomohisa 氏の判定)名前と中身
BF1616.0016.01354.0 GB載らない一致
Q8_08.508.51188.2 GB載らない一致
UD-Q6_K_XL6.567.65169.2 GB載らない+17%
UD-Q5_K_XL5.507.16158.3 GB載らない+30%
UD-Q4_K_XL4.505.03111.3 GB実質不可+12%
UD-IQ4_XS4.254.2493.7 GBぎりぎり密度は一致、置換は 194 テンソル
UD-Q3_K_XL3.444.0790.0 GB使用+18%
UD-IQ3_XXS3.063.7182.0 GB余裕あり+21%
UD-Q2_K_XL2.623.5778.9 GB余裕あり+36%
UD-IQ1_M1.753.3774.5 GB余裕あり+93%
UD-IQ1_S1.563.2872.5 GB余裕あり+110%

判定列は当方のもので、ツールの分類ではありません。ggufaudit は同じ 194 テンソルの 置換を理由に UD の 9 段すべてを mislabeled と分類します。二つに分けたのは結果が違うからで、UD-IQ4_XS だけは IQ4_XSIQ4_NL(4.25→4.50 bpw)と距離が小さく平均が動かず、 名前から体積は読めます。⚠ は「検出済み、実害なし」。Q8_0 と BF16 は 32 ブロックと非量子化なので影響を受けません。

Qwen3.8-Flash-Next の最小 4 段:ファイル名の bpw と実測 bpw、体積を並べたカード。2026-08-29 当方実測
最小 4 段の公称と実測。名前は 1.56〜3.06 bpw、実測は 3.28〜3.71 bpw。ggufaudit 0.1.0 による 2026-08-29 の当方実測。

なぜ 1-bit が 72.5 GB もあるのか——256 で割り切れない幅と tensor_type_fallback()

前回の Flash 比較記事で、Unsloth のドキュメントが 「1-bit 量子化で 72.5GB、RAM は 75 GB 以上」と書いていることに触れました。今回はその「なぜ」 です。

GGUF の k-quant(Q2_K〜Q6_K)と i-quant(IQ1_S〜IQ4_XS)は、重みを 256 個ずつのブロックに 詰める形式です。だからテンソルの第一次元 ne[0](行の幅)が 256 の倍数でないと、その テンソルにはこれらの型を書き込むこと自体ができません。多くの dense モデルは幅が 4096 や 5120 なので問題になりませんが、Flash-Next の expert と dense FFN の幅は 640、320、160 です。 どれも 256 で割り切れません。

このとき llama.cpp の llama-quantize がどうするかは、ソースに関数として書いてあります。 src/llama-quant.cpptensor_type_fallback() (master、2026-08-29 に読んだ版)は、ncols % qk_k != 0 なら警告を一行ログに出してから 型を差し替えます。IQ1_S から IQ4_XS までの i-quant は IQ4_NL(4.50 bpw)へ、Q2_K と Q3_K は Q4_0(4.50 bpw)へ、Q4_K は Q5_0、Q5_K は Q5_1、Q6_K は Q8_0 へ。差し替えた数はカウンタで 数えられ、最後に WARNING: N of M tensor(s) required fallback quantization という一行の まとめが出て、終了コードは 0 です。ファイルには何も記録されません。 general.file_type のメタデータは要求した型のまま、ファイル名は発行元が付けた名前のまま、テンソルごとの 実際の型だけがヘッダに残ります。この挙動は 2023 年 10 月の PR #3747 で意図的に入ったもので、幅の 合わないモデルでも量子化を失敗させずに通すための設計です。失敗させる --no-fallback を 求める issue #26616(2026-08-05)は 執筆時点で open のままでした。

Flash-Next の UD-IQ1_S に当てると、当方の実測はこう読めます(ツール出力の抜粋、 2026-08-29)。

  label: metadata=IQ1_S (general.file_type=24)  filename=IQ1_S
  tensors: 1224   params: 176.94B   bytes: 67.55 GiB
  nominal: IQ1_S -> base type IQ1_S = 1.562 bpw     actual overall: 3.279 bpw   (+110% vs nominal)

  routed experts             144    68.3%    54.9%    2.64   IQ1_S(68) IQ4_NL(48) IQ2_XXS(28)

  DIMENSION-FORCED SUBSTITUTIONS: 194 tensors
    other                     1 tensors -> IQ4_NL  (4.50 bpw)  ncols=160 (%256=160)   28.9% of params
    routed experts           48 tensors -> IQ4_NL  (4.50 bpw)  ncols=640 (%256=128)   22.8% of params

置換された部分は二つあります。一つは幅 160 の N-gram Embedding(PLE)表で、これ一枚が 全パラメータの 28.9%、およそ 51B です。ただしこの表について Unsloth のドキュメントは「ランダムアクセスの ため強く量子化せず、4-bit を下限にする」と最初から書いています。つまり 4.25 bpw を要求して 4.50 になっただけで、ここは実害がありません。もう一つは幅 640 の routed expert 48 テンソル、 全体の 22.8% で、こちらは 1.56 bpw を要求して 4.50 で書かれています。残る 96 個の expert テンソルは幅が 256 で割り切れるので、68 個は本物の IQ1_S、28 個は UD レシピが選んだ IQ2_XXS です。「expert の 3 分の 2 は本当に 1〜2 bit、3 分の 1 は 4.5 bit、そこに設計どおり 4 bit の 巨大な表が乗る」——それが 72.5 GB と 3.28 bpw の中身です。

Reddit の 443 件監査と、その夜の訂正

この挙動を公開ファイルの規模で数えたのが、2026-08-28 の r/LocalLLaMA への u/Daxfortuna 氏の投稿 です。自作の単一ファイル Python ツール ggufaudit で、25 リポジトリ 443 ファイルの ヘッダを読み、64 ファイルで「名前の型が適用できないテンソルが 1% 以上」だったと報告して います(投稿者の自己申告、census は 2026-08-27 付)。最も極端なのは Nemotron-3.5-Lightning で、IQ2 系の 4 ファイルが全部 4.58 bpw、体積差は 20 MB。三つの発行元が同じモデルを出して 三つとも同じ結果だった、というのが「発行元ではなくツールの挙動」と判断した根拠です。当方も 同じ 4 ファイルを 2026-08-29 に測り、4.58 bpw、17.54〜17.56 GiB を確認しています。

bartowski の Nemotron-3.5-Lightning GGUF 各ファイルについて、名前が謳う bpw と実測 bpw を並べたダンベル図
Nemotron-3.5-Lightning リポジトリ全ファイルの公称と実測(投稿者が ggufaudit 0.1.0 で 2026-08-27 に測定)。名前と中身が一致するのは、もともと 32 ブロック型を名乗るファイルだけ。作図 u/Daxfortuna。出典:r/LocalLLaMA — I audited 443 GGUF quants across 25 repos

Flash-Next についてこのスレッドで起きたことは、数字そのものより参考になります。投稿の 当初の記述は「51.9% のパラメータが置換された」でした。それに対して別のユーザーが、 Unsloth のドキュメントにある「PLE は 4-bit 下限」の一文を引いて指摘し、投稿者は約一時間後に 数え直して「本当に置換で下がったのは expert の約 23% で、52% ではない。census を更新した。 ファイルが 1.56 の名前で 3.28 bpw なのは変わらないが、責める相手のテンソルを間違えていた」と 訂正しています。当方の実測でも 51.9% という行は出ますが、この記事では「ツールが数えた 到達範囲」と「実際に密度が下がった 22.8%」を分けて書いているのはそのためです。

もう一つ、言葉について。ツールの判定語は MISLABELED ですが、これは誰かが偽った、という 意味ではありません。レシピは正当、量子化は成功、名前はエコシステム標準のもの、警告は アップロードに含まれないログの中にだけあった——投稿者自身がそう書き、ツールの FAQ も 「直すべきはツールとラベリングで、個々の発行元を責めることではない」としています。実際、 census では同じ発行元の dense モデル(unsloth/Qwen3.8-27B-GGUF、26 段)は置換ゼロで、当方が UD-IQ2_XXS を測っても公称 2.06 に対し実測 2.16、判定は「label is honest」でした。幅が 決めるのであって、作り手が決めるのではありません。

Zenn 二本の選択を読み直す:Q3_K_XL(90 GB)と Q2_K_XL(78.9 GB)の間にあるもの

今週の実測記事二本は、偶然ちょうど 4.07 bpw と 3.57 bpw の段を使っています。

tomohisa 氏は M4 Max 128GB で UD-Q3_K_XL(90.0 GB)を選び、その理由を「量子化の種類ごとの 違いを分かっていなかったので、ファイルサイズが約 90GB で、128GB のマシンに載りそうだ、 という理由だけで決めました」と書いています。その後で調べ直し、一つ上の IQ4_XS は重みだけで 87 GiB あって KV を足すと Metal の割り当て上限に張り付く、下は Mac では IQ 系が遅く 1-bit は Unsloth 自身がエージェント用途に使うなと明記している、として「選択肢はもともとあまり なかった」と結論づけています。実測の bpw で見ると、Q3_K_XL は名前の 3.44 に対して 4.07。 名前より 18% 濃いファイルで、190 回のツール呼び出しがエラー 0 だった、という報告です。

holy_fox 氏(2026-08-27)は RTX 5090 32GB と RAM 128GB で UD-Q2_K_XL(78.9 GB、3 シャード)を使い、64k コンテキストで decode 43〜48 tok/s を出しています。記事中「llama.cpp からは N-gram Embedding を含め 176.94B パラメータとして認識された」とあり、当方のツールが読んだ params: 176.94B と一致します。 この段の実測は 3.57 bpw、名前の 2.62 より 36% 濃い。

この二段の間、体積で 11 GB、bpw で 0.50 の差は本物です。tomohisa 氏が追記で書いているように、 Q2_K_XL に落とすと Metal の残りが 22.5 GiB になり 131k のセッションを計算上 5 本まで 常駐させられる、という交換は成立します。ただし Unsloth の説明では Q2_K_XL 以下で MTP モジュールが外されるので、落とすなら失うものも把握してからです。

一方、Q2_K_XL からさらに下へ行く 3 段には、同じ意味での交換はありません。 78.9 GB から 72.5 GB まで 6.4 GB 減る代わりに、割り切れる 3 分の 2 の expert が 2.6 bit から 1.56 bit に 落ち、割り切れない 3 分の 1 と PLE 表は 4.5 bit のまま動きません。名前が約束する「2.62 → 1.56」ではなく、中身は「3.57 → 3.28」です。Unsloth の自己申告表でも top-1 一致率は Q2_K_XL 85.2% から IQ1_S 80.2% へ下がります。6.4 GB のために払う代価としては、割に合う場面が 少ないだろうと思います。

ダウンロード前に 1 コマンドで確かめる

テンソルごとの型は GGUF ヘッダに全部入っているので、確認は簡単です。Hugging Face の ファイルページをクリックすればテンソル表と型が見えます。IQ2_XXS という名前のファイルで ffn_*_expsIQ4_NL になっていれば、それが答えです。手元でなら llama.cpp の gguf-py に入っている gguf-dump が重みを読まずに同じ表を出します。

リポジトリ全体をまとめて見るなら、投稿者のツールが一番早い。標準ライブラリだけの 単一ファイルで、通信先は Hugging Face の API と Range 読み取りだけです(当方は実行前に ソースを通読し、--selfcheck が ALL PASS になることを確認しました)。

curl -sL -o ggufaudit.py https://raw.githubusercontent.com/JoshBolding/ggufaudit/main/ggufaudit.py
python3 ggufaudit.py --selfcheck
python3 ggufaudit.py hf://unsloth/Qwen3.8-Flash-Next-GGUF --quant UD-IQ1_S

--quant はファイル名どおりに——Unsloth の段は UD-IQ1_S であって IQ1_S ではなく、 一致しないラベルは usage が出るだけです。見る行は二つ。nominalactual overall、 そして DIMENSION-FORCED SUBSTITUTIONS のブロック。前者の差が 15% 以内で後者が無ければ、差はレシピの意図的な混合で、名前は 信じてよい。後者があって前者が大きく離れていれば、名前は「要求」であって「中身」では ありません。体積で判断するなら、名前ではなく actual overall の bpw で段を比べてください。

128GB 機での結論を一行にすると、こうなります。Q3_K_XL が入るなら Q3_K_XL、セッション数か 余裕が要るなら Q2_K_XL、それより下は名前を信じずヘッダを読んでから。 VRAM を超える MoE の回で書いた「載るか」の計算は、今回のようにファイル名の bpw が 中身と違うモデルでは、実測の bpw から始めないと合いません。