実測と生成したサイト

MiniMax-2.5(229B MoE、256エキスパート中8活性)は -ot exps=CPU のExpert Offloadで96GB VRAMに載りました。IQ5_KのDecodeは34〜37 tok/sです。IQ4_NLでReact LP、IQ3_Sで歯科医院の静的サイトを生成しました。

実験環境

項目仕様
CPUAMD EPYC 9175F(Zen 5, 16C/32T, L3 512MB)
GPUNVIDIA RTX PRO 6000 Blackwell Max-Q(96GB VRAM)
メモリDDR5-6400 768GB(12ch)
OSUbuntu 24.04 LTS
Runtimeik_llama.cpp(build 4192)
ContainerPodman rootless

モデル仕様

項目値
アーキテクチャMiniMax-M2(MoE)
サイズ229B.A10B(総229B、活性10B)
レイヤー数62
エキスパート数256(活性8)
学習コンテキスト長196,608
rope freq_base5,000,000

Part 1: Expert Offload ベンチマーク(IQ5_K)

実行コマンド

  podman run --rm -it \
  --device nvidia.com/gpu=all \
  -p 8081:8080 \
  --shm-size 16g \
  --cap-add=SYS_NICE \
  -v "$MO":/models:ro,Z \
  $IMG \
  --host 0.0.0.0 --port 8080 \
  -m "$MODEL" \
  --no-mmap --jinja \
  -c 65536 \
  --threads 13 --threads-batch 25 \
  -b 2048 -ub 2048 \
  -ngl 99 \
  -ot exps=CPU \
  -ctk f16 -ctv f16 \
  --warmup-batch \
  -fa on
  

パラメータの目的です。

  • -ot exps=CPU:157GBの大半を占めるExpert重みをCPUに置きます。
  • -ngl 99:全63層をGPU offload表示にしますが、Expertは -ot で上書きします。
  • --no-mmap:157GBを実メモリへ読み、ページフォールトを避けます。
  • --warmup-batch:起動時にウォームアップします。

メモリ配置

領域サイズ配置先
CPU buffer(Expert重み)157,356 MiB(約154GB)CPU RAM
KV cache15,872 MiB(約15.5GB)CUDA0
Compute buffer1,990 MiBCUDA0
GPU buffer(Attention等)3,579 MiBCUDA0

GPUは約21GBを使い、残り75GBをKV拡張へ使える配置です。

結果: 8連続ラン(65Kコンテキスト設定)

RunPrompt(tok)PP速度(tok/s)Gen(tok)TG速度(tok/s)合計(s)
1753214.0721535.379.6
2386170.3619635.237.8
3297161.3824035.218.7
4341166.1278334.5724.7
51,264205.4673434.5327.4
6942215.2192134.3031.2
7938216.2315734.318.9
81,075176.321,35133.7646.1
指標PP速度(tok/s)TG速度(tok/s)
平均190.6434.66
中央値190.8934.55
最小161.3833.76
最大216.2335.37

別セッション(131Kコンテキスト設定時)

#PP(tok)TG(tok)Ctx使用PP速度(tok/s)TG速度(tok/s)
13,227724,820268.0837.69
42,7085128,223289.8935.96
81,96519211,172313.6035.39

TGは33.7〜37.7 tok/sでした。文脈が蓄積しても急な低下は見られませんでした。

Expert Offloadで確認したこと

  • 速度:8ランのTG変動は約10%でした。PCIe帯域の制約による一定の速度と解釈しています。
  • offload表示:「offloaded 63/63 layers to GPU」でも、Expertは -ot でCPUにあります。
  • prompt cache:6,029トークンで1,460 MiB、23,104トークンで5,596 MiBを保存し、反復時のTTFTが短くなりました。
  • tokenizer警告:special_eos_id is not in special_eog_ids はEOG判定が不安定になる懸念が残ります。

ワンプロンプト生成の実演動画

ワンプロンプトからWebサイトを生成する様子を撮影しました。

動画リンク: https://www.youtube.com/watch?v=zisR4hPfT2c

動画にはAGENTS.mdからの生成、tokenごとの出力速度、生成コードを残しています。

Part 2: React LP ワンショット生成(IQ4_NL)

実行構成

  • 量子化: IQ4_NL(IQ5_Kより軽量、品質はほぼ維持)
  • コンテキスト: 262,144(256K)
  • 入力: AGENTS.md(loFT LLC の詳細なサイト仕様書)
  • スタック: Vite + React + TypeScript + Tailwind CSS v4

検証結果

AGENTS.mdからloFT LLCのコーポレートサイトを生成しました。

生成されたコンポーネント構成(Atomic Design):

  • Atoms: Button, Heading, Text, Icon, Input, TextArea, Badge
  • Molecules: ServiceCard, CaseStudyCard, TestimonialCard, NavItem
  • Organisms: NavBar, HeroSection, ServiceGrid, ProcessTimeline, ContactForm, Footer

実装された機能:

  1. ヒーローセクション(アニメーション背景+関数曲線)
  2. コンタクトフォーム(react-hook-form + zod バリデーション)
  3. SEO最適化(JSON-LD構造化データ、動的メタタグ、favicon自動生成)
  4. SPAルーティング(react-router-dom)

Tailwind v4への修正 npx tailwindcss init の失敗から、CSS-firstの @import "tailwindcss"; へ変えました。従来の tailwind.config.js を使う構成からの修正です。

TypeScriptエラー:初回ビルドに18件ありました。

  • Prop / routingと LegalPage の不整合
  • verbatimModuleSyntax での import type 要求
  • onClick?: () => void と (e: any) => void の不一致
  • React.cloneElement の型問題
  • リファクタリング後の未使用import

ビルドログを読ませ、1回の修正でビルドが通りました。

  vite v7.3.1 building client environment for production...
✓ 147 modules transformed.
dist/index.html                   0.46 kB │ gzip:   0.29 kB
dist/assets/index-BeGmd-zS.css   30.76 kB │ gzip:   5.99 kB
dist/assets/index-CCc5Lf0B.js   357.41 kB │ gzip: 111.66 kB
✓ built in 797ms
  

lsof -i :5173 でdevサーバーを確認し、curl でHTML応答を得ました。title、description、OGP、faviconも更新しました。Web開発の生成物をブラウザで確認できる段階まで進めた記録です。

IQ4_NLでの運用判断

IQ5_Kは157GB、IQ4_NLは約120GBと想定し、転送量の削減を狙いました。54,000トークン超でもLCP similarityによるprompt cacheが働き、反復デバッグに使えました。

Part 3: 歯科医院静的サイト生成(IQ3_S GPU Full Load)

IQ3_Sを選んだ理由

より多くのExpertをGPUへ置き、-ot exps=CPU の遅延を減らすためです。精度との引換えに速度を優先しました。

要件

  • 6ページの静的HTMLサイト(index, services, doctors, info, visit, access)
  • ビルドステップなし、Tailwind CSS (CDN)、Alpine.js (CDN)

結果: 約18分で6ページ完成

ページ主要コンテンツAlpine.jsによる動的機能
index.htmlヒーロー、8サービスカード、医師プレビュー、ニュースモバイルナビ、言語切替UI
services.html14治療カード、FAQセクションカテゴリフィルタリング、アコーディオン
doctors.html6医師プロフィール、専門・資格詳細の展開・収納
info.html料金表、保険対応、支払い方法見積もりモーダル
visit.html初診フロー、予約案内バリデーション付きフォーム
access.html地図、交通機関、駐車場経路タブ切り替え
  • 総所要時間: 18分2秒(設計・実装・Diagnostics含む)
  • 診断結果: エラー・警告なし
  • 品質: IQ3_Sでもアクセシビリティ配慮(ESCキー閉鎖、フォーカス管理)、セマンティックHTML構造が維持された

生成サイトのスクリーンショット

歯科医院サイト:トップページ ヒーローセクションとサービスカード
トップページ — ヒーロー + 8サービスカード
歯科医院サイト:トップページ下部 診療時間・保険情報・フッター
トップページ下部 — 診療時間・初診案内・フッター
歯科医院サイト:料金表・保険対応ページ
料金表ページ — Fee Schedule + 保険・支払い方法
歯科医院サイト:サービスページ カテゴリフィルタとFAQ
サービスページ — カテゴリフィルタ + FAQアコーディオン

量子化レベル別の運用指針

量子化モデルサイズTG速度用途
IQ5_K157.7 GiB34-37 tok/sベンチマーク、品質重視の生成
IQ4_NL~120 GiB(推定)向上見込み長コンテキスト作業、React LP生成
IQ3_S~100 GiB(推定)さらに向上構造明確な大量コード生成、速度優先タスク

今回はタスクに合わせて量子化を下げ、GPUへ多く置く構成も選びました。

サイト生成で得た印象

229Bをローカルで37 tok/s動かせました。独立したExpertをCPUへ置く方法は、VRAMに収まらないMoEの選択肢になります。2つのサイトでは、仕様から複数ファイルの整合性を保ったコードを生成できました。

再現方法

モデル取得

  huggingface-cli download <quantizer>/MiniMax-M2.5-GGUF \
  --include "MiniMax-M2.5-IQ5_K.gguf" \
  --local-dir /mnt/data/hf/hub/models--MiniMax-2.5-GGUF
  

ベンチマーク実行

Part 1のコマンドを使います。ik_llama.cppのExpert Offload対応が必要です。

計測

  curl -s http://localhost:8081/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"minimax","messages":[{"role":"user","content":"Explain MoE architecture"}],"max_tokens":512}'
  

補足ノウハウ

–no-mmapを使う理由

157GBを mmap で読むと、ページフォールトが断続的に起きていました。--no-mmap で実メモリへ読み、推論中の遅延を避けます。起動には数分かかります。

Expert数とDecode速度

MiniMax-2.5は256中8個、GLM-4.7-Flashは64中4個を選びます。選択コストは大きい一方、個々のExpertはFFN 1,536次元と小さく、Expert数だけで速度は決まりません。