Muhtasari
Mradi huu huhudumia DeepSeek V4.1 Flash ndani ya mfumo kwenye mifumo miwili ya NVIDIA GB10 DGX Spark. Unatumia checkpoint ya EXL3 yenye bits-per-weight 2.9, usambamba wa tensor kwenye nodi zote mbili, kernels asilia za sm_121a, na API ya vLLM inayoendana na OpenAI kwenye porti 8888.
Kitambulisho cha modeli inayohudumiwa ni DeepSeek-v4.1-Flash-EXL3. Utekelezaji huu ni wa maandishi pekee na umeundwa mahususi kwa ajili ya kifaa cha nodi mbili za GB10 zilizounganishwa kupitia CX7.
Kontena linaongeza usaidizi wa EXL3 kwenye vllm/vllm-openai:deepseekv41-flash-0909, picha ya vLLM ya ARM64 inayojumuisha usanifu unaohitajika wa DeepseekV41.
Kile Mradi Unachotoa
- Huduma ya ndani inayoendana na OpenAI: Programu zinaweza kuita endpoint ya kawaida ya
/v1/chat/completions. - Usambamba wa tensor kwenye nodi mbili: Modeli inaendeshwa kwa ukubwa wa tensor-parallel 2 kupitia muunganisho wa CX7.
- Quantization ya EXL3: Checkpoint ina wastani wa bpw 2.9 na hutumia codebook ya
mul1pamoja na mipangilio ya quantization kwa kila tensor. - Utabiri wa asili wa DSpark: Draft experts tayari zimehifadhiwa chini ya
mtp.*kwenye checkpoint, hivyo modeli tofauti ya draft haihitajiki. - Usaidizi wa muktadha mrefu: Usanidi uliotolewa huweka
MAX_MODEL_LEN=600000na hutumia hifadhi ya akiba ya KV yenye ukubwa wa 2.5 GiB. - Majedwali ya Engram yanayotegemea faili: Data ya Engram isiyoquantize husomwa kutoka shards asilia za modeli 47 na 48 badala ya kubandikwa kwenye kumbukumbu ya host.
- Uanzishaji wa kiotomatiki:
start.shhupakua weights, hupata au huunda picha, hushiriki faili na worker, huendesha ukaguzi wa GPU, na huanzisha API. - Ulinzi wa wakati wa kuendesha: Kianzishaji hufanya ukaguzi wa nafasi ya kuanzia, huachilia allocators kati ya awamu za prefill, huondoa page cache baada ya kupakia, na hurekebisha alama za OOM za makontena.
Mahitaji ya Vifaa na Hifadhi
Hifadhi hii inalenga nodi mbili kamili za NVIDIA GB10 DGX Spark. Anwani chaguomsingi ya nodi kuu ni 10.0.0.1, na nodi huwasiliana kupitia CX7. README inataja interfaces zilizojaribiwa kuwa enp1s0f1np1/rocep1s0f1 kwenye nodi ya kwanza na enp1s0f0np0/rocep1s0f0 kwenye nodi ya pili.
Panga takriban GiB 387 za data ya modeli:
- Takriban GiB 197 kwa shards 39 za EXL3 kutoka Mia-AiLab/DeepSeek-V4.1-Flash-EXL3-2.9bpw.
- Takriban GiB 190 kwa shards asilia za DeepSeek 47 na 48 pamoja na index. Hizi zina majedwali asilia ya Engram.
- Takriban GiB 9 kwa picha iliyochapishwa ya kontena wakati picha inayolingana inaweza kuvutwa badala ya kujengwa.
Ikiwa tayari una saraka kamili ya DeepSeek-V4.1-Flash, elekeza ENGRAM_DIR kwake ili kuepuka kupakua tena chanzo cha Engram. Ni shards 47 na 48 pekee pamoja na index ndizo zinasomwa kwa madhumuni haya.
Kwenye DGX Spark, RAM ya host pia ni kumbukumbu ya GPU. Kila ugawaji wa CUDA hutumia mara moja kumbukumbu ya pamoja, hivyo mipangilio ya hifadhi na kumbukumbu inapaswa kubadilishwa kwa kujitegemea na kujaribiwa kwa prompt ndefu.
Andaa Nodi Kuu
1. Clone hifadhi na uunde faili la mazingira
Endesha utekelezaji kutoka kwenye saraka ya hifadhi kwenye Spark kuu:
cp .env.example .env
Kianzishaji pia huunda .env wakati wa kuendesha kwa mara ya kwanza ikiwa haipo. Kagua faili hilo na usasishe thamani kama WORKER_USER na GID inapohitajika na mifumo yako.
Thamani zilizotajwa wazi kwenye .env zina kipaumbele kuliko viambishi vya mazingira vya mstari wa amri kwa sababu start.sh hupakia faili hilo juu ya mazingira iliyorithiwa. Kwa mfano, badilisha WEIGHT_SYNC ndani ya .env badala ya kuendesha WEIGHT_SYNC=zfs ./start.sh.
2. Sakinisha zana za upakuaji za Hugging Face
Upakuaji wa modeli kiotomatiki unahitaji CLI ya Hugging Face yenye usaidizi wa uhamishaji:
pip install -U 'huggingface_hub[hf_transfer]'
Upakuaji unaweza kuendelea baada ya kukatizwa. Ikiwa utekelezaji uliokatizwa utaacha modeli haijakamilika, endesha tena kianzishaji au kipakuaji.
3. Pakua kwa hiari bila kuanzisha seva
Ili kuweka faili za EXL3 na Engram kabla ya kuwasha vLLM, endesha:
./download.sh
Upakuaji wa kiotomatiki umewezeshwa kwa chaguomsingi. Weka AUTO_DOWNLOAD=0 kwenye usanidi ikiwa ungependa kusimamia faili hizo mwenyewe.
Anzisha Seva
Kutoka kwenye hifadhi iliyo kwenye nodi kuu, endesha:
./start.sh
Wakati wa kuendesha kwa mara ya kwanza, kianzishaji hufanya shughuli zifuatazo kwa ujumla:
- Hukagua nafasi ya kumbukumbu inayopatikana na usanidi wa nodi.
- Hupakua faili zozote za EXL3 na Engram zinazokosekana.
- Huvuta picha ya umma
ghcr.io/miaai-lab/deepseek-v4.1-flash-exl3-2x-dgx-sparks:2.9bpw. - Huunda ndani ya mfumo pekee ikiwa muhuri wa recipe umebadilika au sajili haipatikani.
- Hufanya weights zipatikane kwa worker.
- Huendesha ukaguzi wa GPU wa EXL3 GEMM na uondoaji wa quantization wa Engram.
- Huanzisha ranks mbili za tensor-parallel na kufichua API kwenye porti
8888.
Checkout safi inapaswa kuendana na muhuri wa recipe kwenye picha iliyochapishwa, hivyo kwa kawaida hakuna haja ya ku-compila.
Dhibiti ujenzi wa picha na uhamishaji
BUILD=1 ./start.shhuunda picha kila mara kwenye mashine ya ndani.SKIP_BUILD=1 ./start.shhuhifadhi picha iliyopakuliwa hata kama muhuri wa recipe yake unatofautiana.SKIP_PULL=1 ./start.shhuepuka kuwasiliana na sajili ya kontena.PULL=1 ./start.shhupakua picha tena hata kama muhuri wa ndani unalingana.SKIP_SHIP=1 ./start.shhuzuia head kunakili picha kwenda kwa worker.
Kwa chaguo-msingi, utumaji wa picha hutumia faili ya tar iliyowekwa kwa hatua na kuhamishwa kupitia rsync inayoweza kuendelea baada ya kukatizwa. Weka IMAGE_SHIP=stream ili kuelekeza docker save moja kwa moja kwenye docker load ya worker. Utiririshaji hauhitaji nafasi ya muda, lakini uhamishaji uliokatizwa huanza tena kutoka mwanzo. Hali ya auto hupendelea uhamishaji unaoweza kuendelea na hurudi kwenye utiririshaji nafasi ya diski ya worker inapokuwa ndogo.
Kagua na Simamia Usambazaji
Tumia amri za usimamizi za launcher badala ya kuendesha kontena hizo mbili kando:
./start.sh status
./start.sh logs
./start.sh logs worker
./start.sh stop
./start.sh restart
Ikiwa worker tayari ina uzani uliosawazishwa, anzisha upya bila kurudia hatua ya usawazishaji:
SKIP_SYNC=1 ./start.sh restart
Wakati wa kuanzisha, kitambua ukimya wa kumbukumbu za sekunde 420 hukusanya ufuatiliaji wa stack wa Python kutoka kwa rank zote mbili. Faili za uchunguzi huandikwa chini ya logs/.
Tuma Ombi Lako la Kwanza la API
Baada ya seva kuwa na afya, tuma ombi la ukamilishaji wa mazungumzo kwenye nodi ya head. Ombi hili la smoke huzima kufikiri ili jibu la moja kwa moja liwe rahisi kukagua:
curl -s http://127.0.0.1:8888/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"DeepSeek-v4.1-Flash-EXL3","messages":[{"role":"user","content":"What is 17*19? Reply with the integer only."}],"max_tokens":32,"temperature":0,"chat_template_kwargs":{"enable_thinking":false}}'
Jibu linalotarajiwa ni 323. Kiteja chochote kinachoendana na OpenAI kinaweza kutumia URL hiyo hiyo ya msingi na kitambulisho hicho cha modeli.
Tumia mipangilio inayopendekezwa ya sampuli
Kwa matumizi ya kawaida ya modeli, mipangilio rasmi ya sampuli ni:
temperature=1.0top_p=0.95- Kufikiri kumewezeshwa
Kiolezo cha mazungumzo kwa chaguo-msingi hutumia kiwango cha juu cha juhudi za kufikiri, kinachowakilishwa na 75. Pia kinakubali low kwa 50, max kwa 100, au nambari kamili kutoka 1 hadi 100.
Ombi linalotumia usanidi unaopendekezwa wa sampuli linaweza kuwa hivi:
curl -s http://127.0.0.1:8888/v1/chat/completions \
-H 'Content-Type: application/json' \
-d '{"model":"DeepSeek-v4.1-Flash-EXL3","messages":[{"role":"user","content":"Explain how tensor parallel inference works."}],"max_tokens":512,"temperature":1.0,"top_p":0.95,"reasoning_effort":"high"}'
Elewa Uondoaji wa Kubashiri wa DSpark
Usambazaji huu hutumia uondoaji wa kubashiri wa DSpark, huku wataalamu wa rasimu wakiwa wamejumuishwa kwenye checkpoint. Hakuna drafter tofauti ya kupakua, kupakia au kutoa huduma.
Usanidi wa msingi wa vLLM ni sawa na:
--speculative-config '{"method":"dspark","num_speculative_tokens":3}'
Checkpoint ina kikomo cha ukubwa wa block ya rasimu cha tano, lakini mpangilio uliosafirishwa hutumia tokeni tatu za kubashiri kwa sababu ulipimwa kuwa wa haraka zaidi kwenye nathari. Ukubwa wa capture unajumuisha 1 2 3 4 6 8 12 18 24, ikiwemo ukubwa wa sita kwa mfuatano miwili unaozalisha tokeni tatu za kubashiri kila mmoja.
DSpark huboresha uondoaji wa mfuatano mmoja katika vipimo vilivyoripotiwa. Kwa batch pana zaidi, izime kwa SPEC_METHOD=none. Hii pia huachilia takriban GiB 3.5. README inaripoti takriban tokeni 31.6 kwa sekunde kwa mtiririko mmoja wa kubashiri, huku utoaji bila kubashiri ukifikia upitishaji wa jumla wa juu zaidi kwenye mitiririko minne.
Simamia Kumbukumbu kwa Usalama
Mgao wa takriban kwa kila nodi unajumuisha uzani wa EXL3 wa GiB 99.5 kwa kila rank, pool ya KV ya GiB 2.5, takriban GiB 5 hadi 7 kwa miktadha, NCCL, nafasi za kazi na grafu za CUDA, pamoja na takriban GiB 9 kwa michakato ya vLLM, Docker, mfumo wa uendeshaji na eneo-kazi.
Vikomo vilivyosafirishwa ni:
MAX_MODEL_LEN=600000MAX_NUM_SEQS=2MAX_NUM_BATCHED_TOKENS=1024- Pool ya akiba ya KV ya GiB 2.5
Muundo wa KV huchaguliwa kiotomatiki kuwa fp8_ds_mla ya DeepSeek. Usipitishie --kv-cache-dtype. Pool iliyopimwa ilihifadhi tokeni 774,400 kwa kikomo cha muktadha cha 614,400, kwa gharama ya takriban KiB 3.4 kwa kila tokeni.
Usikadirie quantization ya checkpoint hii kwa kubadilisha 2.9 kuwa nambari kamili 2. Kigezo chake cha quantization huchaguliwa kwa kila tensor, na wataalamu tofauti waliopitishwa, wataalamu wanaoshirikiwa, matrices za attention, tensor za Engram, tensor za MTP na kichwa cha modeli ya lugha hutumia thamani tofauti.
Baada ya uanzishaji wa awali, head ilibakiza takriban GiB 4.07 hadi 4.21 za kumbukumbu inayopatikana katika majaribio yaliyoripotiwa. Prefill ya tokeni 601,000 ilipunguza nafasi hiyo hadi takriban GiB 2.1. Kwa hivyo, thibitisha mabadiliko baada ya prefill ndefu badala ya mara tu baada ya kuanzisha.
Ongeza mpangilio mmoja tu unaohusiana na kumbukumbu kwa wakati mmoja. README inaonya kuwa kuongeza GiB 0.5 kwenye pool ya KV kunaweza kugharimu takriban GiB 1 ya nafasi ya prefill. Pool ya GiB 3 ilifaulu jaribio fupi la smoke lakini ikashindwa kwenye takriban tokeni 470,000 katika prompt ya tokeni 600,000.
Tumia guard ya hiari ya kumbukumbu kwa uangalifu
scripts/memguard.sh hukagua /proc/meminfo mara moja kwa sekunde na kuua kontena ya ndani ya kutoa huduma baada ya sampuli mbili mfululizo kuwa chini ya DSV41_MEM_GUARD_GIB, ambayo kizingiti chake cha chaguo-msingi ni GiB 1.5.
Linda imezimwa kwa chaguo-msingi kwa sababu haiwezi kubaini ni mchakato gani uliotumia kumbukumbu. Daima huua kontena yake ya vLLM, hata kama mzigo wa kazi usiohusiana kwenye mwenyeji ndio uliosababisha shinikizo hilo. Ili kuiwezesha waziwazi, weka:
DSV41_MEM_GUARD=1
Kwa kazi nzito kwenye mwenyeji, README inapendekeza kuwekea kikomo kazi inayosababisha tatizo badala yake:
systemd-run --scope -p MemoryMax=2G <job>
Usambazaji bado unatumia --oom-score-adj 1000 kwa makontena yote mawili, pamoja na ukaguzi wa awali wa nafasi ya boot, kuachilia allocator baada ya kila prefill, na kuondoa akiba ya kurasa baada ya upakiaji.
Chagua Mkakati wa Kusawazisha Uzito
NFS: chaguo-msingi
NFS ndiyo usanidi unaolingana na kifaa kilichojaribiwa. Hutumia tena exporter ya vllm-fn-nfs, hufichua saraka za EXL3 na slim Engram, na kuziunganisha kwenye makontena ya wafanyakazi kama /model na /engram-src.
./start.sh share
./start.sh
start.sh hutekeleza hatua ya kushiriki kiotomatiki, kwa hiyo amri ya wazi ya share ni muhimu hasa wakati wa kuandaa au kutatua matatizo ya export.
ZFS: nakala za ndani ya nodi
Weka WEIGHT_SYNC=zfs katika .env ili kudumisha dataset ya ndani kwenye kila nodi. ZFS inaweza kuboresha ustahimilivu na kutuma vitalu vilivyobadilika pekee baada ya nakala ya awali. Pia huruhusu kurejesha hali ya awali kwa kutumia snapshot.
Gharama yake ni kubwa: kila nodi inahitaji takriban GiB 385 za nafasi tupu kwenye pool. README inaonyesha kuwa Spark ya pili iliyojaribiwa ilikuwa na takriban GiB 41 pekee, hivyo ZFS haikuweza kutumika huko.
Usanidi wa mfano kwenye kila nodi ni:
sudo apt-get install -y zfsutils-linux
sudo zpool create -f models <vdev>
sudo zfs create -o recordsize=1M -o atime=off -o compression=lz4 \
-o mountpoint=/path/to/model models/dsv41-exl3
sudo zfs create -o recordsize=1M -o atime=off -o compression=lz4 \
-o mountpoint=/path/to/engram models/dsv41-engram
sudo zfs allow -u "$WORKER_USER" create,destroy,mount,receive,snapshot,rollback models
Jaza dataset ya Engram kwa vipande 47 na 48 pamoja na index pekee. Usinakili mti kamili wa modeli asilia wa GiB 476. Ikiwa pool au zfs recv ya mfanyakazi haipatikani, launcher hurudi kwenye utiririshaji.
Rsync: nakala rahisi ya ndani
WEIGHT_SYNC=rsync huunda nakala ya kawaida ya ndani ya nodi bila kuhitaji pool ya ZFS. Haitoi masasisho ya nyongeza ya kiwango cha vitalu kama ZFS.
Fungasha Data ya Engram kwa Prefill ya Haraka
Majedwali ya Engram hubaki katika umbizo asilia la FP8 na si sehemu ya mti wa EXL3 uliopunguzwa uzito. Kwa chaguo-msingi, utekelezaji wa embedding unaotegemea faili hupata safu bila kubandika takriban GiB 47 kwa kila tabaka kwenye kumbukumbu.
Ili kuhamisha faili za safu za Engram zinazohusiana na rank kwenye NVMe ya ndani ya kila nodi, endesha:
./start.sh pack
Ufungashaji huandika takriban GiB 94 kwa kila nodi wakati ukubwa wa tensor parallel ni mbili. Ni wa hiari na hauhitajiki kuanzisha mfumo. Katika majaribio yaliyoripotiwa, faili za Engram zilizofungashwa ndani ziliboresha utendaji wa prefill kwa takriban asilimia 25 hadi 50 kwa sababu kukosa safu kulitumia I/O ya moja kwa moja ya ndani badala ya NFS.
Safu za Engram lazima zibaki zikiwa na aina ya fp8_e4m3fn zinapopitishwa kwenye kernel ya uondoaji wa quantization. Kuzichukulia kama uint8 kunaweza kutoa matokeo yanayoonekana kuwa sahihi lakini yasiyo sahihi.
Endesha Majaribio ya Uthibitishaji
Hazina inajumuisha ukaguzi wa kiwango cha chanzo ambao hauhitaji PyTorch au vLLM:
python3 tests/test_numeric_config.py
python3 tests/test_engram_src.py
python3 tests/test_engram_secondary.py
python3 tests/test_k_map.py
python3 tests/test_memory_log.py
python3 tests/test_exl3_lm_head.py
python3 tests/test_sm120_block64.py
python3 tests/test_h2d_stage.py
python3 scripts/weight_budget.py --tp 2
Jaribio la usawa wa chat-template linahitaji transformers na encoding/encoding.py ya modeli asilia:
python3 tests/test_chat_template.py --src /path/to/DeepSeek-V4.1-Flash
Baada ya API kuanza kufanya kazi, endesha jaribio la smoke la mwisho hadi mwisho:
bash tests/test_smoke.sh
Jaribio la smoke huuliza modeli ihesabu 17*19 na hutazamia 323. Kabla ya kuanzisha huduma, start.sh pia huendesha ukaguzi wa usawa wa GPU na uondoaji wa quantization wa Engram kwenye kontena la muda. Matokeo huandikwa kwenye logs/overlay-verify.log.
Vidokezo vya Juu vya Uendeshaji
- Pendelea DSpark kwa mtiririko mmoja au miwili: Kiwango cha usimbuaji cha mtiririko mmoja kilichoripotiwa kilikuwa tokeni 31.6 kwa sekunde, huku jumla ya tokeni 42.5 kwa sekunde ikipatikana katika mitiririko miwili.
- Zima makisio kwa bechi pana zaidi: Kwa
SPEC_METHOD=none, upitishaji wa mtiririko mmoja ulipungua, lakini upitishaji wa jumla wa mitiririko minne ulifikia tokeni 53.7 kwa sekunde katika jaribio lililoripotiwa. - Panga Engram kwa vidokezo virefu vinavyojirudia: Faili za safu za NVMe za ndani hupunguza utegemezi wa uhamishaji wa NFS wa nodi kuu na zinaweza kuboresha kwa kiasi kikubwa kasi ya kujaza awali.
- Weka utumiaji katika maandishi pekee: Bahasha ya kernel ya SM120 haitoi kernel ya sparse-MLA inayohitajika kwa upana wa tokeni za maono wa modeli.
- Usiwashie tena mitiririko saidizi ya EXL3 bila tahadhari: Utumiaji huendesha mitiririko ya EXL3 kwa kufuatana kwa sababu kernel mbili zilizo kwenye mitiririko tofauti ya CUDA zinaweza kukwama pamoja na bafa moja ya kufuli kwa kila kifaa ya runtime.
- Fuatilia violesura sahihi vya mtandao: NCCL haiwezi kutumia lakabu za loopback za
10.0.0.x. Uchaguzi usio sahihi wa GID kwa kila NIC unaweza kushindikana baada ya takriban dakika moja kwaibv_modify_qperrno 61. - Kagua kumbukumbu wakati wa kujaza awali kwa muda mrefu: Kufanikiwa kuwasha na majaribio mafupi ya smoke hakuthibitishi kuwa hifadhi kubwa zaidi ya KV au mipangilio ya muktadha ni salama.
- Tumia kizindua cha hazina: Huratibu ulandanishi wa NFS au wa ndani, ukaguzi wa awali, uthibitishaji wa picha, uanzishaji wa safu mbili, na uchunguzi.
Utendaji Unaotarajiwa
Vipimo vilivyochapishwa vinaripoti tokeni 31.6 kwa sekunde kwa mtiririko mmoja wa usimbuaji na jumla ya tokeni 42.5 kwa sekunde kwa mitiririko miwili. Kujaza awali kwa vidokezo vifupi kulikuwa takriban tokeni 965 hadi 1,041 kwa sekunde kwa data ya Engram iliyopangwa na kernel za wataalamu zilizowekwa katika makundi.
Kujaza awali kwa vidokezo virefu kwa kawaida huwa polepole zaidi. Mifano iliyoripotiwa inajumuisha takriban tokeni 979 kwa sekunde kwa kidokezo cha tokeni 100,000, tokeni 802 kwa sekunde kwa tokeni 455,000, na tokeni 810 kwa sekunde kwa tokeni 601,000. Matokeo halisi hutegemea umbo la kidokezo, usanidi wa hifadhi, makisio, upana wa bechi, na ukubwa uliosanidiwa wa vipande vya kujaza awali.
Hitimisho
Mradi huu hujumuisha kernel maalum, kipakiaji cha EXL3, utekelezaji wa Engram unaotumia faili, usanidi wa mtandao, vidhibiti vya kumbukumbu, na kizindua kinachohitajika ili kuendesha DeepSeek V4.1 Flash kwenye DGX Sparks mbili za GB10. Anza na mipangilio chaguomsingi iliyotolewa, thibitisha API kwa kutumia jaribio la smoke, kisha rekebisha mpangilio mmoja kwa wakati mmoja. Kwa uendeshaji salama zaidi, tathmini upitishaji na kumbukumbu inayopatikana wakati wa mizigo halisi ya kujaza awali kwa muda mrefu.
