FreeToken: az VRAM ile büyük MoE modelleri
35B parametreli bir MoE modeli GPU'nun 1/7'lik diliminde çalıştırın. Uzmanlar RAM'de durur, GPU'ya akar. Kurulum, ayar ve ölçülmüş rakamlar.
FreeToken MoE modellerine özel bir çıkarım motorudur. Normal bir motor modelin tamamını VRAM'e koymak zorundadır; FreeToken uzmanları host RAM'de tutar, GPU'da bir LRU uzman önbelleği çalıştırır ve kaçanları PCIe üzerinden akıtır. Sonuç: VRAM'e sığmayan bir model, sığıyormuş gibi çalışır.
Aynı donanımda ölçüldüğünde fark büyük: 35B'lik bir MoE modeli 18 GB'lik bir MIG diliminde FreeToken vLLM'in ~2–3 katı, Ollama'nın ~17–24 katı hızda çalıştırıyor (karşılaştırma).
Bu sayfadaki her rakam ölçüldü: H200 NVL'in 1g.35gb ve 1g.18gb MIG dilimleri,
24 vCPU, 120 GB RAM, Qwen3.6-35B-A3B-FP8.
Qwen3.6-35B-A3B → uzman bankası 31.4 GB
MIG dilimi → VRAM 32.3 GB ← model sığmıyor
KV cache 5.0 GB
kalan ~2.9 GB
uzmanlar → host RAM'de, GPU'ya akıyorKurulum
Pod
ubuntu:24.04, MIG dilimi, bol RAM ve disk (model + JIT kernel önbelleği için 200 GB rahat).
Port 1919.
nvidia/cuda:13-devel imajını çekmeyin. ~6 GB ve bu kümede 1 GB'lik bir imaj bile
6.5 dakika sürüyor; containerd zaman aşımına düşüyor. CUDA toolkit'i pod içinde kurmak
aynı sonucu verir, imaj çekme sınırına takılmaz.
CUDA 13 + Python bağımlılıkları
FreeToken driver r580+ / CUDA 13 ister ve kernel'lerini ilk kullanımda JIT derler.
apt-get update
apt-get install -y curl ca-certificates git python3 python3-venv build-essential \
python3-dev ninja-build
curl -fsSL -o /tmp/keyring.deb \
https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
dpkg -i /tmp/keyring.deb && apt-get update
apt-get install -y cuda-toolkit-13-0
export PATH=/usr/local/cuda-13.0/bin:$PATHpython3-dev ve ninja şart — dokümanda yazmıyor, ikisi de kurulumu sessizce bozuyor:
python3-devyoksa Triton kernel derlemesiPython.h: No such file or directoryile düşer.ninjayoksaFileNotFoundError: 'ninja', ardından "Backend worker is gone and cannot be restarted".
Belirti ikisinde de aynı ve yanıltıcı: pod running, /v1/models 200 döner, ama her
istek 503 model is still loading alır ve arka planda süreç sessizce çıkar (exit 0, OOM yok).
FreeToken
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv /opt/ft-venv
uv pip install --python /opt/ft-venv/bin/python "freetoken[accel]"
/opt/ft-venv/bin/ft --versionSunucu
ft serve --model Qwen/Qwen3.6-35B-A3B-FP8 \
--host 0.0.0.0 --port 1919 \
--kv-reserve-tokens 262144--model doğrudan bir HF repo kimliği alır ve indirmeyi kendi yapar. Sunucu OpenAI
(/v1/chat/completions, /v1/models) ve Anthropic (/v1/messages) API'lerini birlikte
sunar.
İlk açılış 37 dakika sürdü — model indirmesi + Triton kernel'lerinin derlenmesi. Bu süre
boyunca /v1/models 200 döner ama istekler 503 model is still loading alır. Sunucu hazır
olduğunda log şunu yazar:
API server is ready to serve on 0.0.0.0:1919Sonraki açılışlar kernel önbelleği sayesinde çok daha hızlı (~2 dakika).
Model seçimi
H200'de NVFP4 kullanmayın. NVFP4 Blackwell'e özgü bir tensor-core formatıdır. H200 (Hopper) bir NVFP4 checkpoint'i yüklerken ağırlıkları BF16'ya geri açar — hem bellek hem hız kazancı tamamen kaybolur. Hopper'ın native formatı FP8.
Yani nvidia/Qwen3.6-35B-A3B-NVFP4 yerine Qwen/Qwen3.6-35B-A3B-FP8.
FreeToken'ın desteklediği MoE ailelerinden bazıları: DeepSeek-V4, GLM-5.x, Qwen3.5/3.6 MoE, gpt-oss, Gemma-4, MiniMax-M2.5, Muse-Glimmer.
KV cache — bağlamı bedavaya büyütmek
Varsayılan ayarla KV'ye çok az yer kalıyor. --kv-reserve-tokens, uzman önbelleği
doldurulmadan önce KV'ye taban ayırır. Dört kurulum ölçüldü, hepsi aynı dilimde:
--kv-reserve-tokens | KV kapasitesi | KV boyutu | hız |
|---|---|---|---|
| (varsayılan) | 8.285 token | 0.16 GiB | 73.8 tok/s |
| 65536 | 65.585 token | 1.25 GiB | 74.4 tok/s |
| 131072 | 131.180 token | 2.50 GiB | 74.6 tok/s |
| 262144 | 262.217 token | 5.00 GiB | 74.2 tok/s |
32 kat bağlam, hızda ölçülebilir kayıp yok. Sebep: uzman bankası (31.4 GB) bu dilime zaten sığmıyor, önbellek kaçırma ağırlıklı çalışıyor; ondan 5 GB kesmek isabet oranını hissedilir ölçüde değiştirmiyor. Modelin tam bağlamını (262.144) açmak serbest.
KV'yi FP8'e düşürmek ya da RAM'e taşımak bu sürümde (0.1.2) yok. Bayrak listesinde
kv-cache-dtype benzeri bir seçenek bulunmuyor; KV yalnızca VRAM'de tutuluyor.
Ölçümler
Aşağıdakiler --kv-reserve-tokens 262144 ile, ısınma isteği sonrasında alındı.
Isınma — en büyük tuzak
| istek | hız |
|---|---|
| ilk (soğuk, uzman önbelleği boş) | 3.05 tok/s |
| ikinci | 73.6 tok/s |
| üçüncü | 73.8 tok/s |
Soğuk istekle ölçüm yapmayın. Aradaki fark 24 kat. İlk istek uzman önbelleğini doldurur; gerçek hız ikinciden itibaren görünür. Bu sayfa yazılırken ilk ölçüm 3 tok/s çıkmış ve motor yavaş sanılmıştı.
Girdi büyüdükçe (çıktı sabit 299 token)
| girdi | süre | tok/s |
|---|---|---|
| 356 | 5.5 s | 54.0 |
| 3.326 | 5.9 s | 50.4 |
| 13.226 | 8.0 s | 37.2 |
| 33.026 | 8.3 s | 36.1 |
Girdi 93 kat büyürken toplam süre yalnızca 1.5 kat arttı — 33 bin token'lık bağlam ~2.8 saniyede işleniyor. Uzun bağlam bu kurulumda ucuz.
Çıktı uzadıkça
| çıktı | tok/s |
|---|---|
| 299 | 54.0 |
| 999 | 82.9 |
| 1.739 | 88.8 |
Sabit bir açılış maliyeti var; uzun üretimde amorti oluyor. Gerçek decode hızı ~89 tok/s.
Eş zamanlı istekler
| paralel istek | toplam verim | en yavaş istek |
|---|---|---|
| 1 | 54 tok/s | — |
| 2 | 97.4 tok/s | 6.1 s |
| 4 | 153.5 tok/s | 7.8 s |
| 8 | 170.7 tok/s | 14.0 s |
Toplam verim üç katına çıkıyor: batch'leme uzman getirmelerini paylaştırıyor — aynı uzman bir
kez çekilip birden çok istekte kullanılıyor. MoE offload'ın en çok kazandığı yer burası.
4'ten 8'e geçişte kazanç azalıyor çünkü sunucu varsayılan olarak max_running_requests=4
ile çalışıyor; fazlası sıraya giriyor ve gecikme iki katına çıkıyor.
Yüksek token — bağlamı gerçekten doldurmak
262K KV açmak bir şey, onu kullanmak başka. 1g.18gb diliminde ölçüldü (çıktı 200 token):
| girdi | süre | prefill hızı |
|---|---|---|
| 76.022 token | 22.3 s | ~3.900 tok/s |
| 190.022 token | 51.4 s | ~3.900 tok/s |
| ~285.000 token | HTTP 400 | pencere aşıldı |
190 bin token'lık bir istem 51 saniyede işlenip cevaplandı — 18 GB'lik dilimde, 35B modelle. Prefill hızı iki ölçümde de sabit: bağlam büyüdükçe doğrusal ölçekleniyor, çökmüyor. Pencereyi aşan istek temiz bir 400 alıyor.
Uzun bağlamda "token/s" yanıltıcıdır — o yalnızca üretilen token'ı sayar, oysa işin yükü girdiyi okumaktadır. Anlamlı metrik prefill hızı (girdi token / süre).
Dilim küçülünce ne kaybediliyor
Aynı model, aynı ayarlar (--kv-reserve-tokens 262144), iki farklı MIG dilimi:
| test | 1g.35gb | 1g.18gb | oran |
|---|---|---|---|
| girdi 356 · çıktı 299 | 54.0 | 32.3 | 0.60× |
| girdi 33.026 · çıktı 299 | 36.1 | 26.7 | 0.74× |
| çıktı 1000 | 82.9 | 51.8 | 0.62× |
| çıktı 2000 | 88.8 | 53.4 | 0.60× |
| 2 eş zamanlı (toplam) | 97.4 | 58.1 | 0.60× |
| 4 eş zamanlı (toplam) | 153.5 | 74.2 | 0.48× |
| 8 eş zamanlı (toplam) | 170.7 | 80.5 | 0.47× |
VRAM yarıya inince hız ~%40 düşüyor, ama model 256K bağlamla çalışmaya devam ediyor.
Sebep bellek tablosunda: 18 GB dilimde kullanılabilir VRAM 15.82 GiB; KV 5 GB alınca uzman önbelleğine ~9.5 GB kalıyor (35 GB dilimde ~26 GB kalıyordu). Uzman bankası 31.4 GB olduğuna göre önbellekte tutulamayan oran %30'dan %83'e çıkıyor — her token daha çok PCIe trafiği demek.
Dar VRAM'de eş zamanlılık daha pahalı. Kayıp tek istekte 0.60× iken 8 eş zamanlıda 0.47×'e iniyor: küçük önbellekte paralel istekler birbirinin uzmanlarını atıyor ve batch'lemenin kazancı eriyor.
Motor karşılaştırması: FreeToken · vLLM · Ollama
Üçü de aynı pod'da, aynı 1g.18gb dilimde, aynı model ve aynı test betiğiyle
ölçüldü. Kurulumlar:
# FreeToken
ft serve --model Qwen/Qwen3.6-35B-A3B-FP8 --host 0.0.0.0 --port 1919 --kv-reserve-tokens 262144
# vLLM 0.28.0
vllm serve Qwen/Qwen3.6-35B-A3B-FP8 --host 0.0.0.0 --port 8000 --cpu-offload-gb 60 --max-model-len 262144 --gpu-memory-utilization 0.92
# Ollama 0.33.3 (GGUF, 22 GB)
OLLAMA_CONTEXT_LENGTH=262144 OLLAMA_HOST=0.0.0.0:11434 ollama serve
ollama pull qwen3.6:35b| test | FreeToken | vLLM | Ollama |
|---|---|---|---|
| girdi 356 · çıktı 300 | 32.3 | 17.6 | ~3.0 |
| girdi 33.026 · çıktı 300 | 26.7 | 8.4 | 2.1 |
| çıktı 1000 | 51.8 | 18.2 | 3.0 |
| çıktı 2000 | 53.4 | 18.3 | 3.0 |
| 2 eş zamanlı (toplam) | 58.1 | 25.6 | 3.2 |
| 4 eş zamanlı (toplam) | 74.2 | 31.9 | 3.4 |
| 8 eş zamanlı (toplam) | 80.5 | 38.1 | 3.4 |
Rakamlar token/s. FreeToken vLLM'in ~2–3 katı, Ollama'nın ~17–24 katı.
Neden bu kadar fark var
FreeToken MoE-farkındadır: yalnızca o token için gereken uzmanları çeker, sıcak olanları GPU önbelleğinde tutar. Diğer ikisinin offload'ı katman bazlıdır — hangi ağırlığın gerçekten gerektiğine bakmaz.
vLLM çalışıyor ama yarı hızda. --cpu-offload-gb 60 ile model yüklendi; MoE'de
--cpu-offload-gb'nin bozuk olduğunu söyleyen eski kayıtlar 0.28.0 için geçerli değil.
Buna karşılık vLLM KV kapasitesinde önde: 453.354 token ayırdı (FreeToken 262.189).
Uzun bağlam kapasitesi önceliğinizse bu bir avantaj.
Ollama GPU'dan düşüyor. 22 GB'lik GGUF 18 GB dilime sığmayınca katmanlar RAM'e taşınıyor ve iş CPU'ya geçiyor. Belirti pod içinde net görünür:
ps -eo pcpu,rss,comm --sort=-pcpu | head
%CPU RSS COMMAND
2072 24105868 llama-server ← ~20 çekirdek, 24 GB RSSOllama eş zamanlılıkta hiç ölçeklenmiyor. 2, 4 ve 8 istekte toplam verim 3.2 → 3.4 tok/s ile sabit kalıyor: hepsi aynı CPU darboğazında sıraya giriyor. En yavaş istek 8 paralelde 705 saniyeye çıkıyor. FreeToken'da aynı testte toplam verim 58 → 80 tok/s'e yükseliyor.
Kıyas neyi ölçmüyor: model VRAM'e sığdığında bu tablo geçersizdir. Sığan bir modelde vLLM'in sürekli batch'lemesi ve olgun zamanlayıcısı öne geçer; FreeToken'ın offload makinesi orada yalnızca ek yüktür. Bu ölçüm sığmayan model senaryosu içindir.
Tuzaklar
1 — hybrid arka ucu bu donanımda işe yaramıyor. ft bench bw bir kez çalıştırılıp
kalibre ediliyor ve sonucu net:
ceilings: CPU STREAM read 197.3 | PCIe H2D 43.0 D2H 38.7 GB/s (threshold 2.0x)
fp8 n/a 51.3 GB/s — offload └─ CPU MoE has no fp8_block weight path; hybrid unavailable
bf16 52.4 51.5 GB/s 1.02x offloadİki sebep birden: FP8'de CPU tarafında ağırlık yolu hiç yok, ve diğer formatlarda da
CPU-MoE ile PCIe hızları neredeyse eşit (1.02x, eşik 2.0x). Aynı sebeple --moe-cpu-layers
ile RAM'e daha çok iş kaydırmak da yavaşlatır.
2 — Küçük model seçerseniz motoru boşa çalıştırırsınız. Aynı dilimde openai/gpt-oss-20b
(MXFP4, ~13 GB) denendi: model VRAM'e tamamen sığdı, FreeToken KV'ye 16 GB / 586 bin token
ayırdı ve offload yazmasına rağmen uzman trafiği hiç olmadı. Ölçülen 59 tok/s sıradan GPU
çıkarımıdır — bu iş için FreeToken'a gerek yoktur. Motorun değeri modelin VRAM'e
sığmadığı durumda ortaya çıkıyor.
3 — Dilim küçüldükçe uzman önbelleği daralır. 1g.35gb'de uzman bankası 31.4 GB ve
önbellek kaçırma ağırlıklı çalışıyor. Daha büyük bir dilim (4g.71gb) hem 4 kat hesap gücü
hem gerçek bir önbellek demektir; aynı model orada belirgin biçimde hızlanmalıdır.
4 — Model yüklenirken 503 normaldir. /v1/models hazır olmadan 200 döner; asıl işaret
logdaki API server is ready to serve satırıdır. İlk açılışta bu satır yarım saat sonra
gelebilir.
Laya — metin üretmeyen karar modeli
Sınıflandırma işini bir LLM yerine 421M'lik bir karar modeline yaptırdık ve ölçtük: kümenin kendisi, dağılımı ve taban çizgileriyle birlikte.
LiteLLM: çok kullanıcılı LLM kapısı
İki vLLM kopyasının önüne kullanıcı anahtarı, token tavanı ve bütçe koyun — ölçülmüş maliyetiyle birlikte.

Gao Kaptan Docs