一 VLM 與 LLM 多輪 Agentic RL:從自定義 rollout 到多模態(tài)上下文管理的完整實踐)
文檔教程人工智能大模型RLHF【免費下載鏈接】Awesome-ML-SYS-TutorialMy learning notes for ML SYS.項目地址https://gitcode.com/gh_mirrors/aw/Awesome-ML-SYS-Tutorial點擊查看免費下載本篇技術(shù)指南圍繞 slime 社區(qū)推出的「VLM/LLM 多輪強化學(xué)習(xí)Agentic Multi-Turn RL統(tǒng)一范式」展開講解如何僅通過編寫一套自定義rollout函數(shù)與交互環(huán)境Environment即可讓視覺語言模型VLM像 LLM 一樣進(jìn)行多輪 Agent 交互訓(xùn)練。讀完本文你將掌握 slime 中--rollout-function-path與--rollout-interaction-env-path的接入方式、多輪「生成 → 環(huán)境交互 → 觀測回傳 → 迭代推理」的循環(huán)設(shè)計與終止條件、環(huán)境接口約定以及 Observation 增量編碼dummy messages delta tokens和多模態(tài)訓(xùn)練張量緩沖合并等工程細(xì)節(jié)并了解其在一套開源倉庫Awesome-ML-SYS-Tutorial中的源碼級佐證與實驗結(jié)果。背景Agentic VLM 為什么需要多輪 RL與傳統(tǒng)的單輪推理Single-turn Inference不同Agentic VLM 的本質(zhì)是連續(xù)交互模型不再是端到端地吐出一個最終答案而是作為決策核心在執(zhí)行動作Action與感知環(huán)境觀測Observation的往復(fù)循環(huán)中不斷演進(jìn)。每一次模型輸出都是對環(huán)境的一次試探環(huán)境每一輪的反饋又為模型下一步行動提供更多信息。這種與環(huán)境的多輪交互被認(rèn)為是 VLM 進(jìn)化為真正智能體的必經(jīng)之路。典型場景包括 Computer Use Agent 與具身智能模型不是孤立的對話機器人chatbot而是深嵌在環(huán)境鏈路中的思維引擎thinking machine。它需要具備審時度勢的能力——輸出 Action 引起環(huán)境狀態(tài)變更UI 狀態(tài)、物理位移等實時捕獲環(huán)境以圖片等豐富形式返回的 Observation并在持續(xù)滾動的長上下文中完成復(fù)雜推理。這正是 slime 協(xié)同 Miles 社區(qū)在 VLM Agentic Training 中攻克的核心場景。得益于其在 LLM Multi-Turn Training 階段就完成的解耦設(shè)計用戶僅需通過--rollout-function-path參數(shù)傳入為 VLM Agent 設(shè)計的交互邏輯即可無縫銜接「自主生成 → 環(huán)境交互 → 多模態(tài)觀測回傳 → 迭代推理」的完整鏈路。其設(shè)計哲學(xué)保持一貫的極致解耦Rollout 邏輯不與任何特定數(shù)據(jù)集格式或交互協(xié)議強綁定環(huán)境如何解析 Action、如何執(zhí)行工具、如何反饋 Observation完全由用戶自由決定。該方案與 SGLang RL 團(tuán)隊近期在 RL 訓(xùn)練穩(wěn)定性、效率與適用場景方面的系列工作一脈相承包括 INT4 QAT 全流程訓(xùn)練見 rlhf/slime/int4/readme-en.md、FP8 全流程訓(xùn)練與采樣、投機采樣見 rlhf/slime/spec/readme-en.md以及 Rollout Router Replay 機制等。核心設(shè)計從第一性原理出發(fā)只需定義采樣與交互邏輯正如文檔反復(fù)強調(diào)的從第一性原理出發(fā)任何 multi-turn 訓(xùn)練本質(zhì)上只需要定義采樣與交互邏輯。以 slime 的 LLM Multi-Turn Training例如 Search-R1 式的自定義采樣為例模型在每一輪根據(jù)當(dāng)前上下文生成動作指令實時捕獲環(huán)境觀測并將其增量注入上下文直至模型決定返回結(jié)論或超出上下文限制。得到完整的 trajectory 后再通過正確的loss mask區(qū)分模型輸出的動作指令loss_mask1與環(huán)境反饋信息loss_mask0。VLM 與 LLM 的多輪采樣并無本質(zhì)區(qū)別只需在每一輪交互中額外維護(hù)并拼接多模態(tài)上下文信息。slime 將 environment 與 rollout 明確解耦——環(huán)境如何解析 Action等設(shè)計完全獨立于采樣與訓(xùn)練之外從而提升了可復(fù)用性與可擴展性。多輪交互迭代邏輯整個多輪循環(huán)由以下 5 個步驟組成初始化任務(wù)從Sample提取prompt與多模態(tài)輸入完成首輪編碼初始化sample.tokens、image_data、multimodal_train_inputs_buffer等為多輪循環(huán)提供初始上下文。模型生成模型產(chǎn)生本回合執(zhí)行的動作追加到上下文并將對應(yīng)位置的 loss mask 設(shè)置為 1這些是模型需要被訓(xùn)練學(xué)習(xí)的動作指令。環(huán)境接受動作把模型輸出傳遞給 envenv 返回 observation可能包含多模態(tài)內(nèi)容。追加 Observation 到上下文將 observation 編碼為下一回合的輸入獲取干凈的prompt_ids詳見下文工程附錄追加到上下文并將對應(yīng)位置的loss_mask設(shè)置為 0VLM 場景下 observation 可能攜帶新的多模態(tài)內(nèi)容因此需要同時維護(hù)兩條鏈路的拼接rollout 側(cè)的image_data每輪把新圖片 encode 后 append訓(xùn)練側(cè)的multimodal_train_inputs每輪 processor 產(chǎn)生的張量需要合并。終止條件由以下限制條件共同決定max_turns最多執(zhí)行max_turns輪交互達(dá)到上限后無論任務(wù)是否完成都將被迫停止token budget為避免采樣長度過長維護(hù)一個可用 token 預(yù)算每次模型生成或追加 observation 都會消耗預(yù)算一旦耗盡就提前停止并標(biāo)記為截斷TRUNCATED確保不超出最大上下文或最大生成限制env done環(huán)境在env.step()中返回doneTrue表示任務(wù)已完成或無法繼續(xù)如已得到最終判定、進(jìn)入終止?fàn)顟B(tài)rollout 立即停止。上圖展示了該設(shè)計的完整閉環(huán)左側(cè)為 Rollout 多輪交互采樣分支Prepare model inputs → SGLang generate → Concate assistant tokensloss mask 1→ Tool Call/Environment Interaction → Encode and Concate Observationloss mask 0→ 終止判斷 → Finalize Sample 拼接多模態(tài) tensor右側(cè)為 Training 分支Megatron/FSDP兩者通過Sample與Update Weights形成 RLHF 迭代閉環(huán)。文檔給出了自定義多輪rollout.generate的偽代碼骨架它完整地對應(yīng)上述 5 步邏輯# Pseudocode: custom multi-turn rollout.generate async def generate(args, sample, sampling_params): # 0) Init: load custom variable like envrionment path and max_turn env load_env_module(args.rollout_interaction_env_path).build_env(samplesample, argsargs) max_turns args.max_turns # injected via --custom-config-path (YAML) # 1) Encode initial prompt and multimodal inputs sample.tokens, image_data, mm_train_buffer init_from_prompt(sample, state) # 2) Turn loop: actor - env - append observation - repeat for _ in range(max_turns): # (a) Actor generation (assistant tokens) response_text, new_tokens, new_logprobs, finish_reason sglang_generate( urlurl, input_idssample.tokens, sampling_paramssampling_params, image_dataimage_data ) append(sample, new_tokens, new_logprobs, loss_mask_val1) # (b) Env step (returns next observation; may include multimodal payload) observation, done, _ env.step(response_text) if done: break # (c) Process and append observation tokens user_msg env.format_observation(observation) obs_ids, obs_image_data, obs_mm_inputs, obs_mm_train encode_observation_delta( user_msg, tokenizerstate.tokenizer, processorstate.processor, toolssample.metadata.get(tools) ) append(sample, obs_ids, [0.0] * len(obs_ids), loss_mask_val0) # (d) Multimodal state update image_data obs_image_data # inference-side image_data if obs_mm_train: mm_train_buffer.append(obs_mm_train) # training-side image_data return sample要點解讀rollout_interaction_env_path指定交互環(huán)境的模塊路徑通過load_env_module加載后調(diào)用build_env實例化環(huán)境max_turns通過--custom-config-pathYAML注入與采樣邏輯解耦每個回合中模型生成的動作 token 以loss_mask_val1追加參與訓(xùn)練環(huán)境觀測 token 以loss_mask_val0追加不參與損失計算僅作為上下文多模態(tài)狀態(tài)沿兩條鏈路同步更新image_data服務(wù)于推理側(cè) SGLang 生成mm_train_buffer服務(wù)于訓(xùn)練側(cè)。環(huán)境接口BaseInteractionEnv為了便于用戶自定義環(huán)境slime 為環(huán)境基類BaseInteractionEnv定義了如下公共接口reset()清空環(huán)境內(nèi)部狀態(tài)step(response_text: str) - (observation: dict, done: bool, info: dict)接收模型輸出返回觀測、是否結(jié)束以及額外信息format_observation(observation: dict) - dict把 observation 轉(zhuǎn)成下一回合要追加的 chat message如果 observation 攜帶multi_modal_data會把圖片放進(jìn) message content。這組接口設(shè)計得非??酥骗h(huán)境只負(fù)責(zé)接收動作、產(chǎn)出觀測、報告終止其余一切工具如何執(zhí)行、觀測如何產(chǎn)生完全由用戶實現(xiàn)從而保證了 rollout 主循環(huán)的穩(wěn)定與可復(fù)用。工程附錄兩個關(guān)鍵工程細(xì)節(jié)Observation Tokens 編碼dummy messages delta tokens在 multi-turn rollout 中每一輪環(huán)境都會返回 observation需要將其編碼成prompt_ids追加到sample.tokens讓下一輪生成能看到環(huán)境反饋。直覺做法是直接對 observation 調(diào)用tokenizer.apply_chat_template([message], tools...)但這會引入一個實際問題chat template 往往會自動插入 system prompt 以及 tool 的使用說明若tools非空例如|im start]system You are a helpful assistant that can use tools to get information for the user. # Tools You may call one or more functions to assist with the user query.You are provided with function signatures within tools/tools XMLtags: tools ...如果每輪都對 observation 直接做上述操作這些文本會被重復(fù)追加到上下文導(dǎo)致兩個問題上下文被重復(fù)內(nèi)容快速撐大浪費 token budget即便這些 observation tokens 在訓(xùn)練中被loss_mask0屏蔽它們?nèi)哉紦?jù)上下文位置可能影響行為分布與穩(wěn)定性。解決方案是采用一個通用技巧用固定的DUMMY_MESSAGES作為模板基座計算其對應(yīng)的 token 數(shù)只取 observation 帶來的增量 tokensdelta tokens。核心思路分三步先對DUMMY_MESSAGES單獨 apply chat template得到dummy_prompt包含 system/tool preamble但不包含本輪 observation再對DUMMY_MESSAGES [message]apply chat template得到formatted_prompt包含相同的 system/tool preamble 本輪 observation用trim_length len(encode(dummy_prompt))得到需要裁剪的前綴長度對formatted_prompt編碼后直接切片prompt_ids prompt_ids[trim_length:]從而確保追加到上下文中的只是干凈的 observation tokens不會把 system/tool preamble 每輪重復(fù)塞入。偽代碼概括如下dummy apply_chat_template(DUMMY_MESSAGES, toolstools, add_generation_promptFalse) full apply_chat_template(DUMMY_MESSAGES [obs_msg], toolstools, add_generation_promptTrue) trim len(encode(dummy)) obs_ids encode(full)[trim:] # delta tokens only這一技巧既節(jié)省了上下文空間又保持了 chat template 語義的完整性system/tool preamble 依然只出現(xiàn)一次。多輪multimodal_train_inputs的緩沖合并多輪 rollout 中每一輪把 observation 編碼進(jìn)上下文時若使用 VLM 的 processor會產(chǎn)出一份供訓(xùn)練側(cè)使用的multimodal_train_inputs一個 dictvalue 往往是torch.Tensor例如圖片相關(guān)的特征信息。關(guān)鍵問題是這些張量是按輪產(chǎn)生的碎片化 tensor而訓(xùn)練最終希望得到拼起來的一整塊 tensor。slime 的策略是先 buffer最后按 key 只做一次torch.cat。實現(xiàn)分兩步逐輪收集到 buffer每次_encode_observation_for_generation(...)產(chǎn)出obs_multimodal_train_inputs時不立即拼接而是執(zhí)行multimodal_train_inputs_buffer.append(obs_multimodal_train_inputs)結(jié)束時統(tǒng)一 merge在_finalize_sample(...)中調(diào)用_merge_multimodal_train_inputs(multimodal_train_inputs_buffer)先把每一輪的 dict 按 key 聚合成values_by_key[key] [t0, t1, ...]對每個 key只做一次torch.cat(values, dim0)得到最終 tensor。這樣每個 key 對應(yīng)的 tensor 只發(fā)生一次大張量分配 一次線性拷貝。相比每輪都 concat 一次其好處是避免反復(fù)大塊顯存分配與拷貝torch.cat每次都會新分配輸出張量并復(fù)制舊內(nèi)容降低碎片化風(fēng)險避免每輪cat時短暫同時持有old new帶來的峰值顯存抖動整體把拷貝/分配開銷從O(n2) 降到 O(n)peak memory 更穩(wěn)定、更不易 OOM。結(jié)合倉庫源碼自定義 rollout 的加載鏈路與數(shù)據(jù)流在 Awesome-ML-SYS-Tutorial 倉庫中rlhf/slime/code-walk-through/readme.md 對 slime 的 rollout 系統(tǒng)進(jìn)行了源碼級走讀可以與本篇文檔的設(shè)計相互印證。Rollout 函數(shù)的動態(tài)加載在RolloutController初始化中對應(yīng) slime 源碼slime/ray/buffer.py框架通過load_function動態(tài)加載用戶指定的 rollout 函數(shù)與 eval 函數(shù)self.generate_rollout load_function(self.args.rollout_function_path) self.eval_generate_rollout load_function(self.args.eval_function_path)這正是--rollout-function-path參數(shù)的核心機制用戶傳入自定義函數(shù)路徑后框架在運行時加載并調(diào)用無需改動訓(xùn)練主循環(huán)。從源碼結(jié)構(gòu)看多輪 VLM 的generate函數(shù)即是通過該機制注冊進(jìn) rollout 主流程的對應(yīng)RolloutController.generate()中的self.generate_rollout(self.args, rollout_id, self.data_source, evaluationFalse)調(diào)用鏈。自定義 rollout 的函數(shù)簽名約定見 rlhf/slime/code-walk-through/original/part-4.mddef generate_rollout(args, rollout_id, data_source, evaluationFalse) - list[list[Sample]]: Args: args: 全局參數(shù) rollout_id: rollout標(biāo)識 data_source: 數(shù)據(jù)源 evaluation: 是否為評估模式 Returns: list[list[Sample]]: 生成的樣本組 return samplesSample 與 loss_mask 的數(shù)據(jù)結(jié)構(gòu)Sample對象承載tokens、response、response_length、reward、loss_mask等字段并帶有Status枚舉PENDING/COMPLETED/TRUNCATED/ABORTED。多輪循環(huán)中每輪追加的 token 與 loss mask 都會寫入sample最終由_convert_samples_to_train_data統(tǒng)一轉(zhuǎn)換為訓(xùn)練數(shù)據(jù)其中l(wèi)oss_masks會校驗長度必須與response_length一致確保動作指令算損失、環(huán)境反饋不算損失的語義在訓(xùn)練端嚴(yán)格生效。關(guān)鍵配置參數(shù)整理自 rlhf/slime/code-walk-through/original/part-4.md 的參數(shù)表參數(shù)說明默認(rèn)值rollout_function_path自定義 rollout 函數(shù)路徑VLM 多輪即在此實現(xiàn)slime.rollout.sglang_rollout.generate_rollouteval_function_path評估函數(shù)路徑-rollout_interaction_env_path交互環(huán)境模塊路徑多輪 VLM 新增-max_turns最大交互輪數(shù)經(jīng)--custom-config-pathYAML注入-rollout_max_response_len最大響應(yīng)長度文中實驗從 4096 上調(diào)到 320004096默認(rèn)腳本rollout_num_gpus_per_engine每個 rollout 引擎使用的 GPU 數(shù)量0.2實驗驗證Qwen3-VL-2B 上的 Agentic Multi-Turn GRPO基于上述設(shè)計團(tuán)隊使用 geo3k 多模態(tài)數(shù)據(jù)集對Qwen3-VL-2B-Instruct進(jìn)行了 Agentic Multi-Turn GRPO 訓(xùn)練以 Megatron-LM 作為訓(xùn)練后端訓(xùn)練腳本對應(yīng) slime 上游倉庫examples/geo3k_vlm_multi_turn/run_geo3k_vlm_multi_turn.py。短輪次/短上下文實驗?zāi)J(rèn)設(shè)置--rollout-max-response-len4096、max_turns3下的訓(xùn)練曲線如下圖中 6 個子圖分別刻畫了 raw reward、平均/最大響應(yīng)長度、重復(fù)率repetition fraction、log probs 與 advantages 隨rollout/step的變化趨勢。從結(jié)果看raw reward 持續(xù)上升并收斂說明 actor model 實現(xiàn)了有效學(xué)習(xí)repetition fraction 很快下降未出現(xiàn)無效語言重復(fù)問題模型的平均響應(yīng)長度顯著縮短模型逐步學(xué)會更高效的推理方式。長輪次/長上下文壓力測試為了進(jìn)一步測試性能與穩(wěn)定性將--rollout-max-response-len從默認(rèn)的 4096 逐漸增加到 32000并將max_turns從 3 調(diào)大到 20得到如下結(jié)果可以看出raw reward 仍穩(wěn)定上升并收斂其他指標(biāo)的變化趨勢幾乎與短上下文、小輪數(shù)時無異說明該設(shè)計在更激進(jìn)的長輪次設(shè)置下依然穩(wěn)定。性能方面與短上下文、小輪數(shù)相比訓(xùn)練時間與采樣時間均有上升且采樣時間與訓(xùn)練時間的比值明顯增大多輪采樣耗時占比更高符合預(yù)期。需要提醒的是如果上下文長度或輪數(shù)設(shè)置過大可能出現(xiàn) OOM需要根據(jù)自身硬件條件和場景合理設(shè)置參數(shù)如上下文長度、max_turns、token budget 等。未來工作方向隨著 multimodal agentic AI 訓(xùn)練需求快速增長VLM multi-turn RL 需要在可擴展性與可診斷性上繼續(xù)加強文檔明確了以下四個方向更穩(wěn)健的回合控制與重試機制當(dāng)前 turn loop 采用for turn_idx in range(max_turns)在環(huán)境穩(wěn)定、交互邏輯簡單時可用但接入更復(fù)雜的交互環(huán)境如 OS 執(zhí)行時env 可能因超時、動作解析失敗、偶發(fā)服務(wù)錯誤而失敗。未來考慮引入 retry 功能將回合推進(jìn)改為while循環(huán)僅在成功完成一次有效交互后才遞增 turn并指定失敗預(yù)算如max_env_retries_per_turn在可恢復(fù)場景下通過env.reset()重試當(dāng)前 turn同時避免無限循環(huán)與不可控的運行時開銷。在多輪采樣中使用各類 async 訓(xùn)練方法提升性能多輪采樣中不同樣本的實際輪數(shù)與長度差異較大少數(shù)超長樣本造成的長尾效應(yīng)可能成為整體吞吐的主要瓶頸。slime 已支持 partial rollout相關(guān)代碼走讀見 rlhf/slime/batch-GAE/ppo-gae-chunk.md但尚未與 VLM 多輪采樣充分適配與測試這將是未來工作方向之一。支持 LLM-as-judge 等更復(fù)雜的交互反饋Geo3K 示例環(huán)境是 rule-based 的最小實現(xiàn)便于驗證鏈路而很多 multi-turn 場景會引入一個 LLM 提供每輪的反饋、批改或評價。由于 rollout 與 env 已解耦引入 LLM judge 本身并不要求修改 rollout 主循環(huán)——用戶只需實現(xiàn)自己的 env 并通過rollout_interaction_env_path替換即可。不過隨著交互邏輯變復(fù)雜當(dāng)前BaseInteractionEnv基類可能偏簡單未來可考慮為環(huán)境接口補充更強能力。更完善的 logging 與 turn-level 指標(biāo)體系未來需補充更細(xì)粒度的指標(biāo)如實際執(zhí)行的輪數(shù)分布、截斷原因分布、env retry 次數(shù)與類型等當(dāng)前日志多為整條軌跡粒度而調(diào)參與排障往往需要輪粒度per-turn的 debug 信息因此計劃支持每輪 logging。結(jié)語本文圍繞 slime 的 VLM/LLM 多輪 Agentic RL 統(tǒng)一設(shè)計完整覆蓋了從第一性原理的采樣邏輯定義、多輪交互循環(huán)與終止條件、環(huán)境接口約定到 dummy messages delta tokens 的觀測增量編碼、multimodal_train_inputs的緩沖合并等工程細(xì)節(jié)并以 Qwen3-VL-2B 在 geo3k 數(shù)據(jù)集上的短/長輪次 GRPO 實驗驗證了方案的穩(wěn)定性。其核心啟示在于通過極致解耦rollout 與環(huán)境分離、訓(xùn)練與采樣分離一套自定義rollout函數(shù)即可同時承載 LLM 與 VLM 的 Agentic 多輪訓(xùn)練而所有多模態(tài)上下文管理、loss mask 語義與張量合并等復(fù)雜工程問題都被收斂在采樣層內(nèi)部解決為后續(xù)接入更復(fù)雜環(huán)境OS 執(zhí)行、LLM-as-judge 等保留了充分的擴展空間。AcknowledgementsXiaole Guo, Nan Jiang, Zilin Zhu, Jin Pan, Jiajun Li, Yuzhe Zhou, Chengxing Xie, Yueming Yuan, Chenyang Zhao贊分享文檔教程人工智能大模型RLHF【免費下載鏈接】Awesome-ML-SYS-TutorialMy learning notes for ML SYS.項目地址https://gitcode.com/gh_mirrors/aw/Awesome-ML-SYS-Tutorial點擊查看免費下載相關(guān)推薦slime 中的 SGLang PD Disaggregation為 Agentic RL 與長上下文 Rollout 拆分 Prefill/Decode 服務(wù)拓?fù)鋝lime 中的 SGLang PD Disaggregation為 Agentic RL 與長上下文 Rollout 拆分 Prefill/Decode 服人工智能大模型強化學(xué)習(xí)RLHF分布式訓(xùn)練slime × Tau-Bench 實戰(zhàn)Agentic 多輪工具調(diào)用環(huán)境下的 RL 訓(xùn)練指南slime × Tau Bench 實戰(zhàn)Agentic 多輪工具調(diào)用環(huán)境下的 RL 訓(xùn)練指南 本文圍繞 slime 開源倉庫中 examples/tau be人工智能大模型強化學(xué)習(xí)RLHF分布式訓(xùn)練slime Agentic RL 接入技術(shù)路線從多輪工具調(diào)用、Agent Runtime Adapters 到 test-based reward 的完整實戰(zhàn)指南slime Agentic RL 接入技術(shù)路線從多輪工具調(diào)用、Agent Runtime Adapters 到 test based reward 的完整實戰(zhàn)人工智能大模型強化學(xué)習(xí)RLHF分布式訓(xùn)練上一篇gh_mirrors/sh1/sh的內(nèi)存分配分析使用trace工具追蹤內(nèi)存分配下一篇Mayan EDMS完整功能解析為什么它是最先進(jìn)的文檔管理系統(tǒng)創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考