FreeTokenをUGREENで動かしてみた
- ccf代表
- 19 時間前
- 読了時間: 15分
はじめに — 前回までと、今回のゴール
前回(続々編)は、UGREEN DXP6800 Pro に eGPU(RTX 2000 Ada 16GB)をつないで Ollama + Zed を構成し、「12B クラスは読めるけど思考できない」という壁にぶつかったところまででした。
今回のゴールはそこから一歩進めて、FlashML-org の FreeToken(MoE モデルの専門家をホスト RAM に置き、VRAM にはホットな専門家の LRU キャッシュだけを持つ推論エンジン)を同じ NAS の Docker で動かし、Zed のコーディング支援を実用レベルにすること。
[MacBook Pro / Zed] ─LAN─ [UGREEN DXP6800 Pro (Docker)]
├ ollama :11434 (既存・そのまま)
└ freetoken :1919 (新設)
─ OCuLink / USB4 ─
[eGPU Dock + RTX 2000 Ada 16GB]ところが実際は、FreeToken のコンテナを組むこと自体より前に巨大な壁が 2 つ立ちはだかりました。1 つは「ホストの NVIDIA ドライバは r580+ (CUDA 13) 必須」という要件。もう 1 つは、いざビルドしようとしたら出た no space left on device から発覚した「10TB ストレージプールが実は一度もマウントされていなかった」という問題です。
この記事は、その 2 つの壁を 1 つずつ実測で崩して、最終的に「45〜50 tok/s・実効コンテキスト 3 万 tokens」で Zed からコーディング支援が使えるようになるまでの記録です。同じ UGOS (Debian 12) 環境でドライバ更新やストレージに悩む人の役に立てば嬉しいです。
1. 前提:FreeToken は「コンテナ側だけ」では動かせない
FreeToken 0.1.2 の要件は Linux x86_64 / driver r580+ (CUDA 13) / Python 3.10–3.13。CUDA カーネルを初回起動時に JIT コンパイルするため nvcc (CUDA 13) を使い、付属の freetoken[accel] も flashinfer cu13 ビルドです。
NVIDIA Container Runtime はホストのドライバ(カーネルモジュール + libcuda)をコンテナにマウントして使うので、コンテナイメージをどう作ってもホストが 535 のままでは原理的に動きません。また Forward Compatibility パッケージ(cuda-compat)はデータセンター GPU 専用で、RTX 2000 Ada のようなワークステーション GPU は対象外。「ホストドライバ ≥ 580」が唯一の解でした。
まずは付属の診断スクリプト(読み取り専用の check-env.sh)で現状を把握:
kernel : 6.12.74+deb12-amd64
OS : Debian GNU/Linux 12 (bookworm)
GPU : NVIDIA RTX 2000 Ada Generation, 535.261.03 ← CUDA 12.2
導入方法: apt (Debian 純正 deb / DKMS nvidia-current)
ヘッダ : あり (/lib/modules/.../build) → DKMS ビルド可
Secure Boot: 無効
Toolkit: 1.19.0 / Docker に nvidia runtime 登録済み良いニュース は「Debian 純正 deb で入っている」「ヘッダがある」「Secure Boot 無効」の 3 点。つまり .run インストーラ不要で、apt 一辺で更新できる見込みが立ちました。ここからドライバ更新の「落とし穴 5 連」が始まります。
2. ドライバ更新、落とし穴 5 連
落とし穴 1: Ubuntu 流のパッケージ名は存在しない
まず NVIDIA CUDA リポジトリ (debian12) を登録して定番の名前を探すと……
$ apt-cache policy nvidia-driver-580 nvidia-driver-580-open | head
nvidia-driver-580:
Installed: (none)
Candidate: (none) ← ?!「リポジトリ登録に失敗した?」と一瞬思うのですが、原因は単純で、debian12 リポジトリのパッケージ名は Debian 流ということ。Ubuntu のネットワークリポジトリにある nvidia-driver-580 のような「ブランチ名つき」名前は存在せず、以下の名前になります:
用途 | パッケージ名 (debian12 repo) |
580 LTS ブランチのメタ(今回使う) | nvidia-open-580(候補 580.178.04-1) |
580 系のもう一つのメタ | cuda-drivers-580 |
素のメタ(最新ブランチに飛ぶ) | nvidia-driver(610.57.04 まで飛ぶので不使用) |
現在入っている Debian 純正パッケージと同名の構成なので、purge 不要の in-place アップグレードで切替できます。
落とし穴 2: DKMS パッケージは「dkms ≥ 3.1.8」を要求する
名前を直してドライランすると、今度はこんなエラー:
$ apt-get -s install nvidia-open-580
nvidia-open-580 : Depends: nvidia-kernel-open-dkms (>= 580.178.04) but it is not going to be installed
Depends: nvidia-driver (>= 580.178.04) but 535.261.03-1 is to be installed
...
E: Unable to correct problems, you have held broken packages.リポジトリの Packages インデックスを直接取得して依存関係を調べたところ、CUDA リポジトリの DKMS パッケージ(open/closed 両方・全バージョン)は
Depends: dkms (>= 3.1.8)を要求していました。一方、Debian bookworm 純正の dkms は 3.0.10-8+deb12u1。つまり nvidia-kernel-open-dkms が「入れられない」状態で、全体の依存解決が崩れていたのです。解決策はシンプルで、CUDA リポジトリ自身が dkms 3.4.1 を配布しているので先に更新:
$ sudo apt-get install -y dkms
$ dkms --version
dkms-3.4.1落とし穴 3: apt の候補が「610」になるため << 581 制約で解決不能になる
dkms を更新しても、まだ同じエラー。ここで pin でも hold でもないことに気づくのに少し時間がかかりました。apt の実挙動が原因です:
$ apt-cache policy nvidia-driver
Installed: 535.261.03-1
Candidate: 610.57.04-1 ← 候補は最新ブランチnvidia-open-580 の依存は、よく見ると上限付きです:
Depends: nvidia-driver (>= 580.178.04), nvidia-driver (<< 581)
Depends: nvidia-settings (>= 580.178.04), nvidia-settings (<< 581)
Depends: nvidia-kernel-open-dkms (>= 580.178.04), nvidia-kernel-open-dkms (<< 581)リポジトリには 580.178.04-1 が存在するのに、apt の候補は 610.57.04-1。apt-get は「候補版」がバージョン範囲を満たさないとき、候補より古い版まで戻って探索せず、即座に失敗するんです(aptitude なら解ける)。これが "held broken packages" の正体でした。
解決策は apt pin で 580 ブランチを候補に固定すること:
$ sudo tee /etc/apt/preferences.d/cuda-580-pin >/dev/null <<'EOF'
Package: nvidia-* libnvidia-* libcuda* libcudadebugger* libegl-nvidia* libgles-nvidia* libglx-nvidia* libxnvctrl* libnvcuvid* libnvoptix* firmware-nvidia-gsp* xserver-xorg-video-nvidia*
Pin: version 580.*
Pin-Priority: 990
EOFこの pin は恒久運用です。580 LTS ブランチ内のセキュリティ更新(580.179 等)は自動で当たりつつ、610 系への勝手な跳躍を防いでくれます。
落とし穴 4: pin の glob 漏れ — exact 依存も「候補版」でしか解決されない
pin を入れて候補が 580.178.04-1 に変わったのに、エラーは別の場所に移動しました:
nvidia-driver-cuda : Depends: libcudadebugger1 (= 580.178.04-1) but it is not going to be installed
nvidia-kernel-open-dkms : Depends: firmware-nvidia-gsp (= 580.178.04-1)犯人は pin の glob から漏れていた 3 つの名前: libcuda1、libcudadebugger1、firmware-nvidia-gsp。いずれも nvidia-* / libnvidia-* にマッチしない名前です。ここで判明したのも面白い挙動で、apt は exact バージョン依存(= X)でも候補版でしか解決しないということ。580.178.04-1 がリポジトリに存在しても、候補が 610 のままだと「その版は入れられない」扱いになります。冒頭の pin の Package: 行に libcuda* libcudadebugger* firmware-nvidia-gsp* を足して完成です。
リポジトリインデックスを機械的に検査して「580.178.04-1 を持つ全パッケージのうち pin 未カバー」を洗い出し、依存チェーン外(cuda-drivers メタ、nvlink5、libnvsdm 等)を除外して確定させました。ここまで来てようやくドライランが通り、約 35 パッケージの in-place upgrade + nvidia-kernel-dkms(535 側)の自動除去 + nvidia-kernel-open-dkms 等の新規導入、という計画が出ました。
本番: インストールと再起動
$ sudo apt-get install -y nvidia-open-580 # DKMS ビルドに数分
$ dkms status
nvidia/580.178.04, 6.12.74+deb12-amd64, x86_64: installed
$ sudo update-initramfs -u
$ sudo reboot # eGPU 接続 + 電源ON のまま
$ nvidia-smi
| NVIDIA-SMI 580.178.04 Driver Version: 580.178.04 CUDA Version: 13.0 |Ada 世代は open カーネルモジュールが NVIDIA 推奨、ということで nvidia-open-580 を使いました。再起動後、UGOS 内蔵のメディアトランスコーダ (media_transcoder) が真っ先に新ドライバで GPU を掴みに来たのには少し感動がありました。Ollama 0.24.0 (CUDA 12.2 ビルド) も下位互換でそのまま動作。「ドライバを上げても既存の CUDA 12 系ワークロードは壊れない」の実証です。
落とし穴 5: libnvoptix の実体だけ消えている
ところが GPU コンテナの再テストで別のエラーが:
$ docker run --rm --gpus all nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smi
nvidia-container-cli: detection error: open failed:
/usr/lib/x86_64-linux-gnu/libnvoptix.so.580.178.04: no such file or directory調べると、libnvoptix1 パッケージは 580.178.04-1 で正常インストール済みなのに、SONAME シンボリックリンク (libnvoptix.so.1) のリンク先の実体ファイル(約 105MB)だけが無い dangling symlink 状態。この検出エラーは Ollama を含む全 GPU コンテナの起動を阻害するので影響大でしたが、再インストール一発で復元できました:
$ sudo apt-get install --reinstall -y libnvoptix1
$ sudo ldconfig
$ docker run --rm --gpus all nvidia/cuda:13.0.0-base-ubuntu24.04 nvidia-smi → OK
$ docker start ollama → OKなお、535 → 580 の切替で Debian 純正の依存が外れ、apt autoremove が glx-alternative-* や linux-headers-6.1.0-44-* を「不要」として提示してくるようになります。これらは UGOS が 6.1 系カーネルで起動した際の DKMS 再ビルド等に必要な場合があるので、今のところ autoremove せず apt-mark manual で保持しています。
3. 「ディスクが一杯」から始まった /volume1 復活劇
いよいよ FreeToken のビルド、と思って docker compose build を走らせると:
failed to solve: ... write /overlay/.../libcufft.so.12.0.0.15: no space left on deviceCUDA 13 devel イメージ(展開で 12〜14GB)を展開中にディスクが尽きました。df -h を見て驚きました。システム兼 Docker 領域の NVMe (107GB) が 100%。そして何より——
/dev/mapper/ug_..._pool1-data (どこにもマウントされていない)
/volume1 (空のディレクトリ)6 本の SSD は生きていた
この NAS、実は 3.6TB ディスクを 6 本搭載しています。lsblk で見ると:
レイヤ | 状態 |
sda〜sdf(各 3.6TB) | Crucial BX500 4TB SSD × 6(ROTA=0 のとおり SATA SSD) |
md1 (RAID6) | active, 6/6 [UUUUUU] — 実効 14.5TB、健全 |
LVM VG ug_..._pool1 | 正常(空き 4.49TB) |
LV data(10TB・ext4) | active なのに未マウント ← これが原因 |
プールは「ほぼ完成」で、最後のマウントだけが毎回失敗していたのです。journal を見ると理由がはっきり出ていました:
Aug 26 15:54:42 systemd[1]: Dependency failed for volume1.mount - /volume1.
Aug 26 15:55:23 storage_serv_ugvolume: pool[pool1] /dev/md1 assemble by 6 diskssystemd は起動時に /volume1 をマウントしようとしてデバイスを 90 秒(既定)待ちますが、UGOS のストレージサービスが md1 と LVM を組み立てるのは起動 +139 秒。毎回負けるレースで、その後は二度と再試行されません。数ヶ月間、10TB のプールが「あるのに無い」状態で、気づけば全データが 107GB の NVMe に押し込められていた、というオチです。
復旧と恒久対策
LVM はもう active なので、その場は 1 コマンドでマウントできます:
$ systemctl start volume1.mount
$ df -h /volume1
/dev/mapper/ug_..._pool1-data 10T 51G 9.4T 1% /volume1恒久対策は fstab のオプションに デバイス待ちタイムアウトの延伸を追加するだけ:
$ sudo cp /etc/fstab /etc/fstab.bak
$ sudo sed -i 's|defaults,noatime,nofail 0 2|defaults,noatime,nofail,x-systemd.device-timeout=10min 0 2|' /etc/fstab
$ sudo systemctl daemon-reloadこれで UGOS のプール組み立てがどれだけ遅くても(10 分以内なら)待ってくれます。UGOS のシステム更新が fstab を書き換える可能性があるので、更新後は grep volume1 /etc/fstab の確認を習慣にするのが安全です。
そして容量設計。NVMe は Docker イメージ置き場として残しつつ、大きいものはプールへ逃がします:
docker イメージの掃除(未使用の ollama:latest 8.2GB、ビルドキャッシュ 4GB 等 → 約 14GB 解放)
未使用 Ollama モデルの削除(qwen3:14b + gpt-oss:20b で約 22GB)
FreeToken のモデル・キャッシュは /volume1/docker/freetoken/data へ bind mount(compose の FT_DATA_DIR で切替)
$ df -h /overlay
/dev/nvme0n1p7 107G 78G 24G 77% ← 0GB から 24GB へ4. FreeToken コンテナ、そして「ゾンビ」事件
compose はこんな構成に落ち着きました:
services:
freetoken:
build:
context: .
args:
CUDA_IMAGE: nvidia/cuda:13.0.0-devel-ubuntu24.04
image: freetoken:0.1.2
container_name: freetoken
restart: unless-stopped
init: true # ← ゾンビ事件 (後述) の対策
gpus: all
ipc: host # CPU オフロードのプロセス間共有メモリ用
shm_size: 16gb
networks: [ai] # 既存の ai ネットワーク (Ollama と同じ)
ports:
- "1919:1919"
environment:
FT_MODEL: ${FT_MODEL:-Qwen/Qwen3.6-35B-A3B-FP8} # .env で上書き
FT_SERVE_ARGS: ""
HF_TOKEN: ${HF_TOKEN:-}
volumes:
- ${FT_DATA_DIR:-freetoken-data}:/data # .env で bind mount 化初回ミスとして、.env に FT_DATA_DIR を書いたのに compose 側の volumes 行が名前付きボリュームのままで、モデル DL (~35GB) が NVMe 側に流れてディスクを再圧迫した事件がありました(compose の .env は「compose ファイル内の ${...} 展開」にだけ効く、という基本の再確認)。もう 1 件、docker compose down が
Error response from daemon: cannot stop container: ... PID 31537 is zombie and can not be killed.
Use the --init option when creating containers...で失敗する「ゾンビコンテナ」事件も発生。PID 1 のプロセス回収不足が原因で、compose に init: true を 1 行足して解決しました。
5. Qwen3.6-35B の初動と、ft bench bw による環境の見極め
まず重めの Qwen/Qwen3.6-35B-A3B-FP8 (~35GB) をロード:
[core|rank=0] INFO Auto-selected attention backend: fi
[core|rank=0] INFO Auto-selected MoE backend: offload
[core|rank=0] INFO --moe-cache-auto resolved moe_cache_size=3015 num_pages=8271
[core|rank=0] INFO API server is ready to serve on 0.0.0.0:1919推論はちゃんと通ります(思考モデルなので reasoning_content に思考が分離されて返る)。ただ、実測すると:
指標 | 値 | 意味 |
decode スループット | ~11-13 tok/s | 35B MoE (活性 3B) としては頑張っているが…… |
実効コンテキスト (num_pages) | 8,271 tokens | 16GB VRAM を重みと KV で取り合い、狭い |
ここで付属の ft bench bw でハードウェア天井を測っておくと、状況がよく分かります:
ceilings: CPU STREAM read 52.3 | PCIe linear H2D 2.9 D2H 3.9 GB/s
per-dtype ... backend = offload (全 dtype)eGPU が OCuLink (PCIe 3.0 x4 相当) 接続なので、GPU への専門家転送帯域は 2.9〜3.9 GB/s しかありません。ホスト RAM の 52.3 GB/s と比べると 13〜18 倍遅い。つまりこの拓環境では 「専門家を CPU 側で実行する offload バックエンドが正解」で、PCIe 経由で専門家を GPU に集める hybrid にする価値はない、というのが数値で出ます。FreeToken が自動選択したとおりでした。benchbw.json は /data にキャッシュされるので、以後の起動でもこの較正が使われます。
6. gpt-oss-20b への切替で「実用」に変わる
「コーディング用途だと 35B は重すぎでは?」というのが気になり始めて、モデルを openai/gpt-oss-20b (~13GB, MXFP4) に切り替えることに。このモデルが本構成に合う理由は 3 つ:
専門家が小さい → 16GB VRAM の LRU キャッシュに載る割合が跳ね上がり、遅い PCIe/CPU 経由に流れる読み取りが激減する
スライディングウィンドウ兼用のハイブリッド注意機構 (SWA) → KV が安価で、同じ VRAM でも実効コンテキストが大きく伸びる
tool-calling / コーディングに強い 20B クラス。Zed のエージェント用途と好相性
切替時にも小ネタが 2 つ。まず .env の HF_TOKEN に日本語のプレースホルダを入れたまま起動すると、トークンが HTTP ヘッダーに入るため UnicodeEncodeError: 'ascii' codec can't encode characters で即死します(ゲート付きモデルなのでトークン発行&ライセンス同意は必須)。次に、compose の environment に FT_MODEL を直書きしていたため .env 側の指定が無視される、という自分の構成ミス。${FT_MODEL:-既定値} 形式に直して解決しました。
で、結果がこちら:
指標 | Qwen3.6-35B-A3B-FP8 | gpt-oss-20b | 改善 |
decode スループット(定常) | ~12 tok/s | ~45-50 tok/s | 約 4 倍 |
実効コンテキスト (num_pages) | 8,271 | 31,082 | 約 3.8 倍 |
KV コスト | 0.16 GiB / 8K | 0.89 GiB / 31K | — |
MoE キャッシュ (VRAM) | 3,015 | 768 | — |
512 token の生成が 19.8 秒(初回 JIT 暖機込み)。定常は 50 tok/s 前後で、ストリーミングの体感は十分「速い」。ファイル文脈を渡せる 3 万 tokens のコンテキストと合わせて、「decode 30 tok/s 以上 + 実効 ctx 3 万以上」という私の実用ラインを両方クリアしました。難物の設計相談だけ Qwen3.6-35B に戻す運用にしています(.env の FT_MODEL を書き換えて up -d するだけ、DL 済みなので数分)。
7. コーディング能力の実測 — 5 問テストで gpt-oss-20b と Qwen3.6 を比較
速度とコンテキストの改善が分かったところで、「コーディング支援として実際に使える品質か」を検証するために、同一の 5 問を両モデルに投げるテストバッチ (test-coding.sh) を書きました。temperature 0・同一プロンプト・同一 max_tokens で比較します。
T1: CSV パーサの実装+境界ケースのテスト自作 (正確性)
T2: バグ埋め込みコードの指摘と修正 (デバッグ)
T3: 嵌った if 文のリファクタリング (設計改善)
T4: ログ集計スクリプト (実務・要件順守)
T5: ツール呼び出し (Zed Agent 互換の要)
テスト | gpt-oss-20b | Qwen3.6-35B (thinking) |
T1 実装+テスト | ◎ 完成。境界ケース 14 個のテストを自作 (2,894 token / 66 秒) | ✗ 思考 7,745 字で予算を使い切り content 空 |
T2 バグ発見 | ◎ 2 バグとも正確に指摘+防御的改良 (23 秒) | ✗ content 空 (思考 5,048 字) |
T3 リファクタリング | ◎ 辞書駆動+dataclass+方針説明 (26 秒) | ✗ content 空 |
T4 実務スクリプト | ◎ 要件 3 点+stderr への報告という設計判断 (32 秒) | ✗ content 空 (思考 7,496 字) |
T5 tool calling | ○ 発火するも extension 引数を落下 (3 回一貫) | ◎ directory + extension を完全指定 |
定常速度 | 41-44 tok/s | 10-12 tok/s (1 問 143-174 秒) |
この比較から読み取れること:
思考モデルの max_tokens は「思考+本体」の総予算。gpt-oss は思考が短く本体に到達できる一方、Qwen3.6 は極めて饒舌な思考 (1 問 5,000-8,000 字) が 12 tok/s の速度と掛け合わさって、予算内でも時間内でも回答に届かない。「品質の潜在力は高いが、このハードでは待てない」が数値で出ました
再現性: temp 0 のため、コンテナ再起動を挟んでも T2〜T4 はバイト単位で同一の出力。キャッシュ (radix cache) と合わせて挙動が追いやすい
速度と丁寧さのトレードオフ: T5 では gpt-oss が 4 秒で発火するが引数を落とし、Qwen は 34 秒かけて完全な引数を組む。エージェント用途では応答性が優先なので gpt-oss、慎重な設計相談なら Qwen、という住み分けの根拠になる
なお検証中に一つ地味な罠を踏んだので記録: FreeToken はリクエストの model 名を検証せず、ロード中のモデルで黙って応答するため、「Qwen に切り替えたつもりが gpt-oss のままで同じ回答が返る」「戻したつもりが Qwen のまま」という事故が 2 回起きました (判別は token 数・速度・思考の言語/形式で可能)。テストスクリプトには実行前に /v1/models の served id と要求名を照合して不一致なら停止する安全装置を入れて解決しています。
結論として 「decode 30 tok/s 以上+実効 ctx 3 万以上+ 5 問テストで実用品質」を満たす gpt-oss-20b を日常用とし、Qwen3.6-35B は時間のかかる deep thinking 用の待機枠、という運用に落ち着きました (Qwen の思考オフ (reasoning_effort=none) 検証は今後の宿題)。
8. Zed からの接続 — 地味に効く 2 つのポイント
Zed は OpenAI 互換エンドポイントを登録できます:
"language_models": {
"openai_compatible": {
"freetoken": {
"api_url": "http://192.168.x.x:1919/v1", // NAS の IP に置換
"available_models": [
{
"name": "gpt-oss-20b",
"display_name": "gpt-oss-20b (FreeToken/eGPU)",
"max_tokens": 30000,
"max_output_tokens": 8192,
"capabilities": { "tools": true, "images": false, /* ... */ }
},
{
"name": "Qwen3.6-35B-A3B-FP8",
"max_tokens": 8192,
"capabilities": { /* ... */ }
}
]
}
}
}ハマりどころは 2 つ:
max_tokens は /v1/models の値ではなく実効 KV プールに合わせる。API はアーキテクチャ上の上限(262144 等)を返しますが、実際に同時に保持できるトークンは起動ログの num_pages(gpt-oss-20b で 31,082、Qwen3.6 で 8,271)で決まります。大きく申告すると長文プロンプトで即エラー。
プロバイダ名の大文字小文字。default_model の "provider": "FreeToken" のように、openai_compatible のキーと一致していないとデフォルトモデルが解決されません(key は freetoken)。
あとは初回のみ API キーを求められるので任意の文字列を入れれば、Agent パネルのモデルセレクタから選べて、思考過程も折りたたまれて表示されます。
9. まとめ — 「実測で潰す」という体験
最終的な構成と数字:
[MacBook Pro / Zed] ─LAN─ [DXP6800 Pro / Docker (freetoken:1919)]
└─ OCuLink ─ [RTX 2000 Ada 16GB]
モデル: gpt-oss-20b (MXFP4, ~13GB)
専門家: ホスト RAM (offload backend, CPU 52.3GB/s 実測)
定常 decode: 45-50 tok/s / 実効 ctx: 31,082 tokens
補助: Qwen3.6-35B-A3B-FP8 (難物用, .env 切替)
Ollama :11434 は CUDA 12 ビルドのまま 580 ドライバで並走振り返ると、この旅の本質は「エラーメッセージを信用して、リポジトリのインデックスや起動ログのような一次情報に当たって、仮説を 1 つずつ実測で潰していく」ことだったと思います:
ドライバ更新は 5 つの落とし穴(パッケージ命名 / dkms 3.1.8 / 候補 610 vs << 581 / pin の glob 漏れ / libnvoptix の欠落)の連続でしたが、すべて apt の挙動とパッケージの依存メタデータから説明できました
「/volume1 が空」の正体は systemd の 90 秒タイムアウトと UGOS のプール組み立て (+139 秒) の毎回負けるレースでした
モデル選びは「VRAM 16GB + 遅い PCIe」というハードウェア特性に、MoE のキャッシュ設計をどう合わせるか、という問題で、ft bench bw の実測が判断の拠り所になりました
前回の結論は「12B は読めるが思い出せない」。今回は「35B クラスの MoE なら、eGPU 16GB でもコーディング支援が実用になる」まで来ました。同じ NAS の Ollama は相変わらず 11434 で生きていて、簡単な補完や軽いチャットはこちら、本気のコーディングは FreeToken、という住み分けができています。
次回は(もしあれば)Ollama のモデル庫を /volume1 へ引っ越して NVMe をさらに解放する話か、UGOS のシステム更新を挟んでもこの構成が生き残るかの実証レポートあたりを書きたいと思います。


コメント