解碼數(shù)據(jù)合成:基于 SLURM 的分布式合成數(shù)據(jù)生成實(shí)戰(zhàn)指南)
人工智能大模型模型優(yōu)化模型量化模型壓縮【免費(fèi)下載鏈接】Model-OptimizerA unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc. It compresses deep learning models for downstream deployment frameworks like TensorRT-LLM, TensorRT, vLLM, etc. to optimize inference speed.項(xiàng)目地址https://gitcode.com/GitHub_Trending/te/Model-Optimizer點(diǎn)擊查看免費(fèi)下載導(dǎo)讀本文聚焦 NVIDIA Model-Optimizer 倉(cāng)庫(kù)中examples/speculative_decoding示例自帶的 SLURM 數(shù)據(jù)準(zhǔn)備方案講解如何將大規(guī)模合成對(duì)話數(shù)據(jù)的生成任務(wù)切分成多個(gè) shard分片通過(guò)salloc分配多節(jié)點(diǎn)、由 vLLM / SGLang 推理服務(wù)并行調(diào)用基礎(chǔ)模型逐片生成、最終合并回完整訓(xùn)練集的全流程。讀完本文你將掌握sharding_utils.py的分片/合并用法、launch.sh的 10 個(gè)命令行參數(shù)語(yǔ)義、worker 在節(jié)點(diǎn)上的真實(shí)執(zhí)行鏈路服務(wù)啟動(dòng)、溫度掃描、斷點(diǎn)續(xù)跑并能直接把它復(fù)用到你自己的投機(jī)解碼EAGLE / DFlash訓(xùn)練數(shù)據(jù)生產(chǎn)中。為什么需要 SLURM 數(shù)據(jù)準(zhǔn)備投機(jī)解碼Speculative Decoding通過(guò)在 GPU 內(nèi)存中部署一個(gè)輕量草稿模型draft model與主模型協(xié)作用一次前向驗(yàn)證多個(gè)候選 token從而加速自回歸生成。要讓草稿模型的輸出分布盡可能貼近主模型訓(xùn)練數(shù)據(jù)最好由主模型自身生成——這就是合成數(shù)據(jù)生成Data Synthesis環(huán)節(jié)的價(jià)值詳見(jiàn) examples/speculative_decoding/README.md 的 Data Synthesis 小節(jié)。但在億級(jí)樣本規(guī)模下單機(jī)串行生成是不可行的每個(gè)樣本都要經(jīng)過(guò)一次完整的推理調(diào)用耗時(shí)以小時(shí)計(jì)。為此倉(cāng)庫(kù)在examples/speculative_decoding/distributed_generate/目錄下提供了完整的 SLURM 并行化支持其基本思路是把輸入 jsonl 按固定行數(shù)切成多個(gè) shard用salloc/ SLURM 作業(yè)分配 N 個(gè)計(jì)算節(jié)點(diǎn)每個(gè)節(jié)點(diǎn)上啟動(dòng) vLLM或 SGLang推理服務(wù)串行處理分配給自己的若干個(gè) shard全部處理完成后把 shard 合并回單個(gè) jsonl作為后續(xù)訓(xùn)練數(shù)據(jù)。整個(gè)過(guò)程假設(shè)$SLURM_JOB_ID已存在即你已在交互式分配或作業(yè)腳本環(huán)境中并假定已選定節(jié)點(diǎn) n1、n2、n3、n4。第一步用 salloc 分配計(jì)算節(jié)點(diǎn)文檔給出的分配命令是salloc -N4 -A account -p partition -J account-synthetic:data-gen -t 120各參數(shù)含義參數(shù)說(shuō)明-N4申請(qǐng) 4 個(gè)節(jié)點(diǎn)-A accountSLURM 賬戶名計(jì)費(fèi)賬戶-p partition目標(biāo)分區(qū)partition-J account-synthetic:data-gen作業(yè)名用于在 squeue 中識(shí)別本次數(shù)據(jù)生成任務(wù)-t 120分配時(shí)長(zhǎng) 120 分鐘注意這里是分鐘單位執(zhí)行成功后salloc會(huì)為當(dāng)前 shell 綁定一個(gè)$SLURM_JOB_ID后續(xù)srun --jobid$JOB_ID ...才能把任務(wù)調(diào)度到這批節(jié)點(diǎn)上。倉(cāng)庫(kù)中還有一份可直接提交的作業(yè)腳本示例 examples/speculative_decoding/collect_hidden_states/slurm_dump.sh它展示了#SBATCH -A account_name、#SBATCH --nodes1 --ntasks-per-node4 --gpus-per-node4、-t 04:00:00等典型 SBATCH 寫法可作參考。第二步用 sharding_utils.py 創(chuàng)建數(shù)據(jù)分片合成數(shù)據(jù)生成是每個(gè)樣本一次推理天然適合并行切分。倉(cāng)庫(kù)用 sharding_utils.py 完成分片與合并兩個(gè)方向的操作。分片shardpython3 distributed_generate/sharding_utils.py --input_path /data/train.jsonl --output_dir /data/train/ --max_lines_per_shard 10000從源碼看該腳本的參數(shù)與行為如下參數(shù)默認(rèn)值作用--input_pathNone輸入 jsonl 文件路徑分片模式下必填--output_dirNone輸出目錄分片模式下必填不存在會(huì)自動(dòng)os.makedirs創(chuàng)建--max_lines_per_shard10000每個(gè) shard 最多包含的行數(shù)達(dá)到上限即滾動(dòng)到下一個(gè) shard 文件--combineFalse切換為合并模式見(jiàn)下文分片文件的命名規(guī)則是train-{shard_idx:05d}-{shard_idx:05d}.jsonl例如train-00000-00000.jsonl、train-00001-00001.jsonl。也就是說(shuō)一個(gè) 40 萬(wàn)行的輸入文件按max_lines_per_shard10000切分后會(huì)得到train-00000到train-00039共 40 個(gè) shard——這正是后文前 40 個(gè) shard的由來(lái)。合并combinepython3 distributed_generate/sharding_utils.py --input_dir /data/output/ --output_path /data/output.jsonl --combine合并模式--combine的邏輯見(jiàn)combine_jsonl_files函數(shù)值得注意只收集目錄下以.jsonl結(jié)尾的文件并按文件名排序后依次讀取跳過(guò)空白行跳過(guò)帶有finished: true標(biāo)記的記錄——這是server_generate.py在全部對(duì)話生成完畢后寫入的完成哨兵見(jiàn)下文刪除每條記錄的conversation_id字段后以 JSON 每行jsonl格式寫入--output_path。因此合并輸出是干凈的訓(xùn)練 jsonl可直接喂給 main.py 或launch_train.sh進(jìn)入 EAGLE 訓(xùn)練流程。第三步用 launch.sh 在 SLURM 上并行生成命令形態(tài)bash distributed_generate/launch.sh $SLURM_JOB_ID vllm TinyLlama/TinyLlama-1.1B-Chat-v1.0 /data/train/ /data/output /scripts/ 0 10 n1,n2,n3,n4 \You are a helpful assistant.\對(duì)照 launch.sh 第 20 行打印的 Usage10 個(gè)位置參數(shù)語(yǔ)義為位置參數(shù)本例取值含義1$1$SLURM_JOB_ID當(dāng)前 SLURM 作業(yè) ID供srun --jobid使用2$2vllm推理后端必須是vllm或sglang否則腳本直接報(bào)錯(cuò)退出3$3TinyLlama/TinyLlama-1.1B-Chat-v1.0基礎(chǔ)模型路徑/名稱將被掛載到容器內(nèi)/model/4$4/data/train/輸入 shard 目錄掛載到容器內(nèi)/input_data/5$5/data/output輸出目錄腳本會(huì)先mkdir -p掛載到/output_data/6$6/scripts/modelopt/examples/speculative_decoding的絕對(duì)路徑內(nèi)含server_generate.py與distributed_generate/掛載到/scripts/7$70start_shard從第幾個(gè) shard 開(kāi)始處理斷點(diǎn)續(xù)跑的關(guān)鍵見(jiàn)下文8$810jobs_per_node每個(gè)節(jié)點(diǎn)處理多少個(gè) shard9$9n1,n2,n3,n4逗號(hào)分隔的節(jié)點(diǎn)名列表10${10}You are a helpful assistant.可選 system prompt透?jìng)鹘o生成腳本注意$6scripts 路徑必須指向倉(cāng)庫(kù)中 examples/speculative_decoding 的絕對(duì)路徑因?yàn)?worker 容器內(nèi)會(huì)調(diào)用/scripts/distributed_generate/worker.sh與/scripts/scripts/server_generate.py。執(zhí)行語(yǔ)義launch.sh 的核心循環(huán)第 54-66 行對(duì)每個(gè)節(jié)點(diǎn)執(zhí)行一次srun --outputsrun_worker_${node}.log --jobid$JOB_ID -N 1 --ntasks1 --ntasks-per-node1 -w $node \ --mpi pmix --overlap --container-image$CONTAINER_IMAGE \ --container-mounts$MODEL_PATH:/model/,$DATA_PATH:/input_data/,$OUTPUT_PATH:/output_data/,$SCRIPTS_PATH:/scripts/ \ bash /scripts/distributed_generate/worker.sh $counter $BACKEND $JOBS_PER_NODE $SYSTEM_PROMPT 關(guān)鍵點(diǎn)每個(gè)節(jié)點(diǎn)通過(guò)-w $node精確釘?shù)揭粋€(gè)計(jì)算節(jié)點(diǎn)-N 1 --ntasks1保證每個(gè)節(jié)點(diǎn)只有一個(gè) srun 任務(wù)使用Pyxis 容器--container-image與--container-mounts。默認(rèn)鏡像按后端區(qū)分——vllm 用vllm/vllm-openai:v0.24.0sglang 用lmsysorg/sglang:v0.5.3-cu129可通過(guò)環(huán)境變量CONTAINER_IMAGE覆蓋例如本地.sqsh鏡像四個(gè)目錄以只讀/可寫方式統(tǒng)一掛載模型、輸入分片、輸出、腳本worker 以后臺(tái)并行啟動(dòng)每個(gè)節(jié)點(diǎn)的counter累加JOBS_PER_NODE腳本最后會(huì)wait所有 worker任一失敗則整體以非零碼退出并在日志srun_launch.log中記錄每條 srun 命令。以本例4 節(jié)點(diǎn)、每節(jié)點(diǎn) 10 個(gè) shard為例節(jié)點(diǎn) n1 處理 shard 0-9n2 處理 10-19n3 處理 20-29n4 處理 30-39即前 40 個(gè) shard。每個(gè) shard 含 10000 行每節(jié)點(diǎn)實(shí)際完成的樣本數(shù)為jobs_per_node × max_lines_per_shard。第四步增量續(xù)跑——處理后續(xù) shard一次salloc分配 120 分鐘可能不夠處理全部數(shù)據(jù)但不需要重新申請(qǐng)worker 會(huì)記錄已生成的conversation_id并跳過(guò)見(jiàn)下文斷點(diǎn)機(jī)制而 launch.sh 的start_shard參數(shù)支持精確續(xù)跑。處理下一個(gè) 40 個(gè) shard即 shard 40-79bash distributed_generate/launch.sh $SLURM_JOB_ID vllm TinyLlama/TinyLlama-1.1B-Chat-v1.0 /data/train/ /data/output /scripts/ 40 10 n1,n2,n3,n4這里start_shard40于是節(jié)點(diǎn) n1 處理 40-49、n2 處理 50-59、n3 處理 60-69、n4 處理 70-79。只要節(jié)點(diǎn)仍在分配時(shí)段內(nèi)就可以反復(fù)這樣續(xù)跑直到所有 shard 處理完畢。launch.sh 第 68 行會(huì)打印Will process shards $START_SHARD through $((counter - 1))供你核對(duì)本次范圍。深入 worker.sh節(jié)點(diǎn)上的實(shí)際執(zhí)行鏈路worker.sh 是每個(gè)節(jié)點(diǎn)上的真正執(zhí)行者理解它能幫你排查超時(shí)、OOM、端口沖突等問(wèn)題。環(huán)境變量與啟動(dòng)參數(shù)worker.sh 接收 4 個(gè)位置參數(shù)_CURRENT_COUNTER本節(jié)點(diǎn)起始 shard、BACKEND、JOBS_PER_NODE、SYSTEM_PROMPT其余行為由環(huán)境變量控制環(huán)境變量默認(rèn)值含義BASE_PORT8000推理服務(wù)起始端口多服務(wù)按 GPU 遞增SGLANG_TP_SIZE1SGLang 張量并行度vLLM 后端下始終 TP1NUM_TEMPERATURES8溫度掃描數(shù)量即每張卡一個(gè)溫度實(shí)例的實(shí)例數(shù)MAX_TOKENS4096單輪生成的最大 token 數(shù)透?jìng)鹘oserver_generate.pyMODEL_NAMEmodel服務(wù)的--served-model-nameSTARTUP_TIMEOUT_SECONDS600服務(wù)健康檢查超時(shí)GPU_COUNTnvidia-smi -L行數(shù)容器內(nèi)可見(jiàn) GPU 數(shù)用于校驗(yàn) NUM_TEMPERATURES 是否越界TEXT_NUM_THREADSTP1 時(shí) 64否則 320客戶端并發(fā)線程數(shù)腳本做了嚴(yán)格的輸入校驗(yàn)backend 必須為 vllm/sglang、GPU_COUNT必須 0、TP 規(guī)模不得超過(guò) GPU 數(shù)、NUM_TEMPERATURES不得超過(guò) GPU 數(shù)TP1 場(chǎng)景等。服務(wù)啟動(dòng)與健康檢查當(dāng)SGLANG_TP_SIZE1時(shí)worker 會(huì)為每張 GPU 啟動(dòng)一個(gè)獨(dú)立服務(wù)vLLM 或 SGLang端口為BASE_PORT gpuCUDA_VISIBLE_DEVICES$gpu vllm serve /model/ \ --tensor-parallel-size 1 --served-model-name $MODEL_NAME \ --port $port --host 0.0.0.0 --trust-remote-code # sglang 時(shí)等價(jià)于python3 -m sglang.launch_server --model-path /model --tp 1 --port $port ...隨后進(jìn)入健康檢查循環(huán)反復(fù) curlhttp://localhost:${port}/health全部返回 200 才繼續(xù)默認(rèn) 600 秒超時(shí)。全部服務(wù)就緒后只有 MPI rank 0PMIX_RANK/OMPI_COMM_WORLD_RANK執(zhí)行生成邏輯避免重復(fù)。溫度掃描與 shard 處理worker 把每個(gè) GPU 上的服務(wù)與每檔溫度一一對(duì)應(yīng)溫度0.0, 0.1, ..., 0.(NUM_TEMPERATURES-1)分別打到不同端口同一 shard 可生成多個(gè)溫度變體對(duì)應(yīng)多條對(duì)話隨后依次處理start_shard到end_shard范圍內(nèi)的每個(gè) shard輸入 shard 路徑按printf /input_data/train-%05d-%05d.jsonl拼出與 sharding_utils 命名嚴(yán)格對(duì)應(yīng)缺失或空 shard 自動(dòng)跳過(guò)[ ! -s $shard ] continue因此中途失敗不會(huì)阻塞輸出文件名為output-%05d-%05d-temp-0.X.jsonl每個(gè) shard 調(diào)用一次python3 /scripts/scripts/server_generate.py \ --data_path $shard --output_path $output \ --num_threads $TEXT_NUM_THREADS --max_tokens $MAX_TOKENS \ --temperature $temperature --url http://localhost:$port/v1 \ --log_empty_conversations [--system_prompt $SYSTEM_PROMPT]TP1 時(shí)SGLANG_TP_SIZE1所有 GPU 組成一個(gè)張量并行服務(wù)、只有一個(gè)端口溫度掃描退化為對(duì)該端口的串行調(diào)用。生成腳本 server_generate.py 的斷點(diǎn)機(jī)制worker 最終調(diào)用的 server_generate.py 是 Medusa 數(shù)據(jù)生成腳本的適配版基于openai客戶端走 OpenAI 兼容 API。它保證斷點(diǎn)續(xù)跑安全啟動(dòng)時(shí)掃描已有輸出文件收集已完成的conversation_id并跳過(guò)輸出文件已含finished: true哨兵時(shí)直接退出All conversations already generated每條完成記錄寫入conversation_id、conversations可選truncated: true全部處理完后追加一行{finished: true}——這正是 sharding_utils 合并時(shí)用于過(guò)濾已完成記錄的依據(jù)。因此即使某個(gè)節(jié)點(diǎn)在中途掛掉重新以相同start_shard啟動(dòng)同一批 shard 也不會(huì)重復(fù)生成只會(huì)補(bǔ)齊缺失的conversation_id。參數(shù)方面--num_threads默認(rèn) 256即并發(fā)請(qǐng)求數(shù)/批大小、--temperature默認(rèn) 0.0、--max_tokens默認(rèn) 2048、--url默認(rèn)http://localhost:8000/v1、--api_key默認(rèn)token-abc123與 README 中vllm serve ... --api-key token-abc123 --port 8000的示例一致。多模態(tài)擴(kuò)展launch_multimodal.sh 與 worker_multimodal.sh除純文本外倉(cāng)庫(kù)還提供面向視頻 VLM 數(shù)據(jù)的并行生成入口 launch_multimodal.sh。與文本版的主要差異僅支持sglang后端使用 SGLang 原生視頻客戶端參數(shù)位支持兩種順序可把media_path放在節(jié)點(diǎn)列表前... jobs_per_node media_path [num_frames] nodes [system_prompt]也可把節(jié)點(diǎn)列表放在前面... jobs_per_node nodes media_path [num_frames] [system_prompt]腳本通過(guò)判斷第 9 參是否含/或.前綴來(lái)自動(dòng)識(shí)別額外的掛載點(diǎn)MEDIA_PATH:/media_data/并為 OpenAI API 模式起一個(gè)本地http.server默認(rèn)端口 18080把媒體目錄暴露為可訪問(wèn) URL默認(rèn)SGLANG_TP_SIZE8、MAX_TOKENS6144、NUM_FRAMES默認(rèn) 32支持API_MODEopenai、VISION_TOKEN_FORMAT默認(rèn) qwen_vl等環(huán)境變量worker 調(diào)用 server_generate_vlm_sglang.py589 行負(fù)責(zé)把視頻/圖片路徑解析、抽幀后構(gòu)造帶視覺(jué) token 的請(qǐng)求。多模態(tài) shard 的輸入輸出命名與文本版一致同樣可以復(fù)用sharding_utils.py分片、合并。關(guān)聯(lián)場(chǎng)景SLURM 上的隱藏狀態(tài) dump數(shù)據(jù)準(zhǔn)備的另一條并行路徑是離線訓(xùn)練所需的 base model 隱藏狀態(tài)導(dǎo)出見(jiàn) collect_hidden_states/slurm_dump.sh。這份 SBATCH 腳本示范了 SLURM 數(shù)組作業(yè)Array Job用法SLURM_ARRAY_TASK_ID作為 DP rank、SLURM_ARRAY_TASK_COUNT作為 DP world size通過(guò)trtllm-llmapi-launch python3 .../compute_hidden_states_trtllm.py --tp 4 --dp-rank $SLURM_ARRAY_TASK_ID --dp-world-size $SLURM_ARRAY_TASK_COUNT實(shí)現(xiàn)節(jié)點(diǎn)內(nèi) TP、跨數(shù)組 DP 的并行。它與本文的合成數(shù)據(jù)生成是互補(bǔ)的兩種 SLURM 場(chǎng)景共同服務(wù)于投機(jī)解碼訓(xùn)練的數(shù)據(jù)準(zhǔn)備。最佳實(shí)踐與注意事項(xiàng)小結(jié)先分片再并行max_lines_per_shard建議根據(jù)單 shard 處理時(shí)長(zhǎng)與作業(yè)窗口-t估算避免一個(gè) shard 拖垮整批節(jié)點(diǎn)或頻繁續(xù)跑。善用start_shard續(xù)跑續(xù)跑時(shí)從上次結(jié)束的 shard 編號(hào)開(kāi)始worker 與 server_generate.py 的雙重?cái)帱c(diǎn)機(jī)制可保證不重復(fù)、不遺漏。容器鏡像可控離線集群可用CONTAINER_IMAGE指向本地.sqsh鏡像避免從 registry 拉取Pyxis 要求掛載源路徑在srun前已存在因此 launch.sh 會(huì)先mkdir -p $OUTPUT_PATH。溫度多樣性與并發(fā)NUM_TEMPERATURES與 GPU 數(shù)綁定TP1 時(shí)多溫度可提升合成數(shù)據(jù)多樣性客戶端線程數(shù)TEXT_NUM_THREADS決定單 shard 內(nèi)的并發(fā)請(qǐng)求量。完成后務(wù)必合并訓(xùn)練前用--combine把output-*.jsonl合并為單個(gè) jsonl腳本會(huì)自動(dòng)剔除空對(duì)話與finished哨兵。整套方案全部位于 examples/speculative_decoding/distributed_generate 目錄配合 examples/speculative_decoding/README.md 中的 Data Synthesis 小節(jié)單機(jī)版server_generate.py用法即可從單機(jī)平滑擴(kuò)展到多節(jié)點(diǎn)集群為 EAGLE 系列草稿模型訓(xùn)練生產(chǎn)高質(zhì)量合成數(shù)據(jù)。贊分享人工智能大模型模型優(yōu)化模型量化模型壓縮【免費(fèi)下載鏈接】Model-OptimizerA unified library of SOTA model optimization techniques like quantization, distillation, pruning, neural architecture search, speculative decoding, etc. It compresses deep learning models for downstream deployment frameworks like TensorRT-LLM, TensorRT, vLLM, etc. to optimize inference speed.項(xiàng)目地址https://gitcode.com/GitHub_Trending/te/Model-Optimizer點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Cell Mixer 單細(xì)胞轉(zhuǎn)錄組數(shù)據(jù)混合合成指南基于 10X 數(shù)據(jù)的細(xì)胞混合物生成與格式轉(zhuǎn)換Cell Mixer 單細(xì)胞轉(zhuǎn)錄組數(shù)據(jù)混合合成指南基于 10X 數(shù)據(jù)的細(xì)胞混合物生成與格式轉(zhuǎn)換 導(dǎo)讀 Cell Mixer 是 google research人工智能深度學(xué)習(xí)NLP計(jì)算機(jī)視覺(jué)強(qiáng)化學(xué)習(xí)3步完成黑蘋果配置OpCore Simplify終極EFI生成指南3步完成黑蘋果配置OpCore Simplify終極EFI生成指南 想要在普通PC上安裝macOS黑蘋果卻苦于復(fù)雜的OpenCore配置OpCore S開(kāi)發(fā)工具CLIOumi 數(shù)據(jù)合成實(shí)戰(zhàn)指南使用 oumi synth 一鍵生成高質(zhì)量合成訓(xùn)練數(shù)據(jù)Oumi 數(shù)據(jù)合成實(shí)戰(zhàn)指南使用 oumi synth 一鍵生成高質(zhì)量合成訓(xùn)練數(shù)據(jù) 導(dǎo)讀 本文基于 Oumi 倉(cāng)庫(kù)中的 configs/examples/syn人工智能大模型預(yù)訓(xùn)練微調(diào)強(qiáng)化學(xué)習(xí)模型推理服務(wù)模型評(píng)測(cè)MCP 服務(wù)分布式訓(xùn)練模型量化創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考