WorldVLN 训练与闭环链路深度整理:从世界模型到 Action-aware GRPO

发布时间:2026/10/25 6:33:38

WorldVLN 训练与闭环链路深度整理:从世界模型到 Action-aware GRPO 1 简介1.1 这篇文章讲什么这篇文章面向第一次接触 WorldVLN 的读者。目标不是记住每个脚本名而是理解一条完整链路自然语言指令和真实画面如何变成无人机动作以及闭环试飞结果如何反过来改进世界模型。文章只把网络公开资料作为背景校准把实现细节落在当前仓库的infer/、train/、Worldmodel/和action_aware_grpo/代码上。1.2 为什么需要闭环空中视觉语言导航的困难不在于看懂一张图而在于动作会改变下一刻的观测。无人机向前、偏航、上升或下降都会让第一视角画面发生连续变化。如果模型只根据当前帧输出动作它会忽略动作后果对后续判断的影响。arXiv 页面把 WorldVLN 定义为在 3D 环境中根据自然语言进行闭环感知与动作。官方项目页强调它基于 observe-act-update 的闭环过程。这不是一次性分类而是不断观察、行动、修正的系统问题。1.3 闭环协议一句话版这类闭环在仓库里最终落到同一个 HTTP 接口反复调用而不是一次性上传完整未来。首轮1 帧真实图像 instruction - 预测 16 个动作 后续执行 16 个动作 - 回传 16 帧真实图像 - 再预测 16 个动作2 核心思想2.1 不是直接动作是先预测世界变化WorldVLN 的关键思想是把导航建模成 prediction-driven world-action problem。模型先预测 latent world evolution再根据预测后果采取行动。落实到仓库主线不是image - action而是real observation prefix instruction - summed_codes - actions。summed_codes是世界模型预测出的 latent 世界转移用于让动作解码器获得接下来世界如何变化的结构信号。对应到仓库真实代码infer/server.py中的_predict_delta_actions_impl()是总调度器四层逻辑清晰可见# infer/server.py: _predict_delta_actions_impl() 主流程简化def_predict_delta_actions_impl(req)-PredictDeltaActionsResponse:# 第一层session 管理 — 获取/创建 TrajectoryStatesession_id_SESSION_ALIAS.get(external_session_id,external_session_id)st_get_or_create_traj(session_id,raw_prompt,req.negative_promptor)# 第二层真实帧入库 — 解码 base64 并追加到 st.frames_cpunew_imgs[_load_image_from_base64(s)forsinreq.images_base64]foriminnew_imgs:tinfinity_transform(im,tgt_hst.tgt_h,tgt_wst.tgt_w)st.frames_cpu.append(t.cpu())# 第三层segment ready 判定# 默认n points[seg1] 才输出future 模式n points[seg] 就输出nst.num_frames()can_emitnpoints[seg1]# 或 allow_future_segments 时 n points[seg]# 第四层世界模型预测 动作解码infer_res_infer_latents_for_actions_and_advance_cache(st,segment_indexseg,seedseed,advance_gt_obs_to_nextcan_emit)actions_stage2_predict_16_actions_for_segment_cm_deg(stst,infer_resinfer_res)returnPredictDeltaActionsResponse(actionsactions,segment_indexseg,...)其中预测世界这一步由_infer_summed_codes_for_step()完成# infer/server.py: _infer_summed_codes_for_step()# 它不直接输出动作而是让 InfinityStar 根据 prompt 真实观测帧# 预测一段 latent 视频轨迹 summed_codes。st.stream.correction_clear_pred()# 清理上一轮预测 cachesummed_codes,pred_vid_infer_summed_codes_for_step(st,step_isegment_index,obs_lenobs_len,# 当前可信任的真实帧数量infer_num_framesinfer_num_frames,# 让世界模型预测的窗口长度seedlocal_seed,top_kstep_top_k,top_pstep_top_p,injectioninj,# gt_obs / official_leak / hybridneed_pred_videoneed_pred_video,)# summed_codes 形状: [1, 16, pt, H, W] — 这就是世界如何变化的 latent 表达2.2 外部概念到仓库实现的映射从公开信息看WorldVLN官方项目页列出三个重点自回归 WAM、Action-aware GRPO、以及真实无人机部署。本文把这些外部结论对应到仓库实现公开概念仓库实现入口Autoregressive WAMWorldmodel/runtime/infinity/infer/server.pyClosed-loop observe-act-updateinfer/client.pysession_idimages_base64Action-aware GRPOaction_aware_grpo/reward_uavflow.pyReal-world deploymentREADME 中的推理、训练和 rollout 脚本# 在线推理服务bashinfer/run_server.sh# 世界模型监督训练bashtrain/scripts/train_from_base.sh# 动作解码器训练分 Stage A 蒸馏 Stage B 监督bashtrain/action_decoder/scripts/train_stageA_ddp.shbashtrain/action_decoder/scripts/train_stageB_ddp.sh# Action-aware GRPO分 collect trainbashaction_aware_grpo/scripts/run_stagea_collect.shRUN_IDmy_runbashaction_aware_grpo/scripts/run_stageb_partialfreeze.shRUN_IDmy_run3 基础协议3.1 两个 checkpoint 的角色在线服务需要两个不同角色的权重。INFINITY_CKPT是世界模型权重负责预测 latent 世界变化。STAGE2_LATENT2ACTION_CKPT是动作解码器权重负责把 latent 转成可执行动作。把二者混用轻则加载失败重则产生语义完全错误的输出。GRPO StageB 产出世界模型 checkpoint动作 Stage B 产出 latent-to-action checkpoint。# 服务启动时必须同时指定两类权重exportPYTHON_BIN$(whichpython)exportINFINITY_CKPT/path/to/infinity/global_step_xxx.pthexportSTAGE2_LATENT2ACTION_CKPT/path/to/stage2_latent2action_combined.ptbashinfer/run_server.sh服务端启动后/health接口可以确认权重是否加载成功# infer/server.py: health 接口返回的关键字段{status:ok,ts_ckpt_loaded:True,# 动作解码器是否加载stage2_ckpt:/path/to/...,# 动作解码器路径infinity_loaded:True,# 世界模型是否加载num_frames:49,step:16,points:[1,17,33,49],# segment 边界}3.2 时间协议49 帧、48 动作、16 步一段帧是状态点动作是两个状态点之间的边。49 帧对应 48 个相邻动作。仓库默认step1648 个动作被切成 3 段。服务端内部用_obs_points()函数计算 segment 边界# infer/server.py: segment 边界计算def_obs_points(pred_num_frames:int,step:int)-List[int]: 闭环 segment 边界公式points [1, 1step, 12*step, ..., num_frames] 例如 pred_num_frames49, step16 时返回 [1, 17, 33, 49] endint(pred_num_frames)pts[1]k1whileTrue:v1k*int(step)ifvend:breakpts.append(v)k1ifpts[-1]!end:pts.append(end)returnpts时间线全景49 frames: frame0 ... frame48 48 actions: frame0-frame1 ... frame47-frame48 clip1: frame0 - frame16, 16 actions clip2: frame16 - frame32, 16 actions clip3: frame32 - frame48, 16 actions server points: [1, 17, 33, 49] (1-based)3.3 Latent 时间压缩17 帧对应 5 个 latent视频 VAE 压缩时间维对应关系由InfinityConfig.pt_total()计算# infer/server.py: InfinityConfig 中的 latent 时间长度计算defpt_total(self)-int:返回整条 RGB 序列对应的 latent 时间长度默认 video VAE 时间压缩率为 4。# latent_index(frame f) (f - 1) // temporal_compress_rate 1return(int(self.num_frames)-1)//41一个 17 帧 segment 对应 5 个 latent。动作解码器需要起点 latent 后续 4 个新 latent来描述 16-action 运动。第二段复用上一段终点 latent保证动作片段在时间上连续。seg0: [latent1, latent2, latent3, latent4, latent5] - 16 actions seg1: [latent5, latent6, latent7, latent8, latent9] - 16 actions seg2: [latent9, latent10, latent11, latent12, latent13] - 16 actions ↑ 段间公共边界last_latent_1代码中的last_latent_1就是段间公共边界的实现# infer/server.py: _infer_latents_for_actions_and_advance_cache() 注释# seg0 使用上一段保存的 last_latent_1 作为边界再拼当前段的 4 个新 latent。# latent5 只是一帧边界 latent保留它是为了让相邻段在 frame17 这个公共边界上连续。4 世界模型训练4.1 Stage-1 SFT训练会预演的世界模型Stage-1 监督训练不直接回归动作。它训练 InfinityStar 在语言条件下预测真实视频的 latent token。训练数据来自视频 JSONL记录视频路径、帧范围、fps 和 caption。脚本采样 49 帧经 video VAE 编码再把文本条件和视觉 token 送入自回归模型做 teacher-forcing。这个阶段给模型建立导航视频 latent 会怎样演化的先验。{video_path:relative/or/absolute/path/to/video.mp4,begin_frame_id:0,end_frame_id:48,fps:16.0,tarsier2_caption:A UAV flies over a road.}训练脚本期望的目录结构train/ ├── train.py # 主训练脚本 ├── scripts/train_from_base.sh # 启动入口 ├── checkpoints/ │ ├── text_encoder/flan-t5-xl-official/ │ ├── infinitystar_videovae.pth │ └── infinitystar_8b_480p_weights/ ├── data/ │ └── your jsonl shard directory # 分 8 片的 JSONL └── outputs/关键环境变量可覆盖默认路径# 文本编码器exportT5_PATHcheckpoints/text_encoder/flan-t5-xl-official# Video VAEexportVAE_PATHcheckpoints/infinitystar_videovae.pth# 基础模型分片权重exportTORCHSHARD_RESUME_PATHcheckpoints/infinitystar_8b_480p_weights# 训练数据目录exportVIDEO_DATA_PATHdata/uavflow_49f_from_40_60_split8_jsonl5 动作解码器训练5.0 为什么需要 TimeSformerTSFormer动作解码器的任务是从 latent 时空特征中读出无人机的 6D 飞行动作。一个朴素方案是直接用 MLP 回归但 MLP 只能逐帧独立映射无法理解连续帧之间的运动关系——而运动关系恰恰是动作的本质。TimeSformerDivided Space-Time Attention Transformer是 Facebook 提出的视频理解模型通过交替的时间注意力和空间注意力天然具备从视频 token 序列中提取帧间运动模式的能力。WorldVLN 利用这一预训练能力把 TSFormer 作为动作解码器的骨干网络设计动机 • 动作 帧间运动的数值表达位移 旋转 • TSFormer 的 divided space-time attention 已经学会看视频理解运动 • 复用预训练权重无需从零学习时空关系 系统定位 latent → VAE decoder 中间特征 → Adapter → [TSFormer] → 6D 动作 ↑ 运动感知骨干核心推理引擎TSFormer 在两个训练阶段中扮演不同角色阶段TSFormer 状态角色目的Stage A冻结参数不更新Teacher真实 RGB → TSFormer patch embedding → “标准 token”Adapter 学习让 VAE 特征也能产出相同格式的 tokenStage B加载预训练可微调Backbone接收 Adapter 输出的 token用 4 帧滑窗推理每窗口输出 3 个 6D 动作 delta简言之Stage A 让 Adapter 学会说 TSFormer 听得懂的语言Stage B 让 TSFormer 利用预训练的时空理解能力从这些 token 中读出实际飞行动作。5.1 Stage AAdapter 蒸馏Stage A 解决的是语言不通的问题。真实 RGB 经过 frozen TimesFormer patch embedding 得到 teacher tokenslatent 经过 VAE decoder 中间层 hook 和 Adapter 得到 student tokens。训练目标是让两者对齐。这里不使用动作标签也不判断轨迹是否成功。它只训练一座桥让 latent 走出来的 token 更像 TimesFormer 熟悉的输入。# train/action_decoder/tools/train_stageA_ddp.py: 蒸馏 loss 组合lossw_cos*L_cosw_mse*L_msew_mean*L_meanw_std*L_stdStage A 必需环境变量exportMANIFEST_JSON/path/to/manifest.json# 训练数据清单exportTSFORMER_CKPT/path/to/tsformer.pth# frozen TimesFormer 权重exportINF_VAE_PATH/path/to/videovae.pth# Video VAE 权重bashtrain/action_decoder/scripts/train_stageA_ddp.sh训练数据清单格式{items_train:[{latent_path:path/to/latents.pt,traj_json_path:path/to/preprocessed_logs.json,images_dir:path/to/images}]}5.2 Adapter 的内部结构Vae96ToTSformerEmbedAdapter是动作解码器中最关键的形状转换层。它接收 VAE decoder 的 96 通道时空特征(B,96,T,H,W)通过卷积和 16x16 patch 投影得到(B*T,480,384)token。直接取 VAE 中间特征而不完整解码成 RGB因为动作头需要运动和几何信息而不是纹理细节。# Worldmodel/action_decoder/src/models/vae96_to_tsformer_adapter.pyclassVae96ToTSformerEmbedAdapter(nn.Module):defforward(self,f96_up3):# 输入VAE decoder 中间层 96 通道时空特征B,C,T,H,Wf96_up3.shape# (B, 96, T, H, W)# 时间维并入 batchxf96_up3.permute(0,2,1,3,4).reshape(B*T,C,H,W)# resize 到动作头训练使用的空间比例xF.interpolate(x,size(192,640),modebilinear,align_cornersFalse)# 卷积精炼 16x16 patch 投影hself.conv_a(x)hself.patch(h)# patch projection# 输出 token 序列tokensh.flatten(2).transpose(1,2).contiguous()# (B*T, 480, 384)returnself.out_norm(tokens),int(T),int(h.shape[-1])形状变化全景VAE decoder 中间特征 (B, 96, T, H, W) - permute reshape (B*T, 96, H, W) - interpolate (B*T, 96, 192, 640) - conv_a (B*T, C, 192, 640) - patch 16x16 (B*T, C, 12, 40) - flatten transpose (B*T, 480, 384) - LayerNorm (B*T, 480, 384) TimesFormer-compatible tokens5.3 Stage B从 latent 到 6D 动作Stage B 接在 Stage A 后面开始使用专家轨迹标签。latent 走 VAE decoder hook 和 Adapter然后交给 TimesFormer 的 4 帧滑窗。每个窗口输出 3 个相邻动作 delta多个窗口重叠平均切出 16 个动作。训练内部用 m/radAPI 对外输出[dx_cm, dy_cm, dz_cm, droll_deg, dyaw_deg, dpitch_deg]。这一步产出STAGE2_LATENT2ACTION_CKPT。# infer/server.py: _stage2_predict_16_actions_for_segment_cm_deg() 核心注释 数据流 1. 从 infer_res.summed_codes 得到整段预测 horizon 的 z_ext 2. VAE decoder Adapter 生成整段 tokens_tnd 3. 对当前 segment 只取左侧上下文 [ctx_start..clip_end]不看右侧未来帧 4. 用 window4 的 TimesFormer 滑窗推理并对重叠帧做平均 5. 切出本 segment 对应的 16 个动作并转成 cm/deg 关键公式 - meters - cm: *100, radians - degrees: *180/pi - 4 帧滑窗聚合 delta[t] sum(predictions covering t) / count[t] 具体例子seg0seg0: obs_len1, next_obs_len17, 需要输出 16 个动作 TimesFormer 输入token 覆盖帧 1..17 窗口数量 K 17 - 4 1 14 个窗口打包成一个 batch 每个窗口输出 3 个相邻帧 delta frame4 的 delta 来自 3 个窗口的平均 [1,2,3,4] 的第 3 个输出 [2,3,4,5] 的第 2 个输出 [3,4,5,6] 的第 1 个输出 最终输出frame2..frame17 共 16 个动作 (cm/deg)Stage B 必需环境变量exportMANIFEST_JSON/path/to/manifest.jsonexportTSFORMER_PRETRAINED/path/to/tsformer.pthexportADAPTER_CKPT/path/to/stageA_adapter.pth# Stage A 产出exportINFINITYSTAR_VAE_PATH/path/to/videovae.pthbashtrain/action_decoder/scripts/train_stageB_ddp.sh6 在线推理服务6.1 HTTP 接口在线推理入口是infer/server.py中的/v1/predict_delta_actions。请求体包含session_id、instruction、本轮真实 RGB 图像images_base64。返回体里的actions默认每段 16 个动作单位 cm/deg。# infer/server.py: 请求体完整定义classPredictDeltaActionsRequest(BaseModel):session_id:str# 轨迹标识符同一条路线多次请求必须保持一致instruction:Optional[str]None# 导航指令首次请求必须提供prompt:Optional[str]None# instruction 的兼容别名negative_prompt:Optional[str]images_base64:List[str]# base64 编码的 RGB 图像首次 1 帧后续 16 帧reset_session:boolFalse# 强制开启新 sessionaction_head_mode:strtsformer_latent# Stage-2 latent-to-actionallow_future_segments:boolFalse# 允许提前发射动作prefix_mode:boolFalse# True每次携带完整前缀seed:Optional[int]None# infer/server.py: 响应体完整定义classPredictDeltaActionsResponse(BaseModel):actions:List[List[float]]# [dx_cm, dy_cm, dz_cm, droll_deg, dyaw_deg, dpitch_deg]segment_index:int# 本次输出哪个 segment-1 表示尚未 readynum_received_frames:intprefix_latents:intdone:boolused_prompt:Optional[str]NoneFastAPI 入口用全局锁保证 GPU 推理串行# infer/server.py: FastAPI 路由入口app.post(/v1/predict_delta_actions,response_modelPredictDeltaActionsResponse)asyncdefpredict_delta_actions(req:PredictDeltaActionsRequest):if_LOCKisnotNone:asyncwith_LOCK:return_predict_delta_actions_impl(req)return_predict_delta_actions_impl(req)6.2 客户端闭环协议infer/client.py展示了客户端如何按协议发送帧。核心是_post_frames()函数# infer/client.py: _post_frames() 核心逻辑def_post_frames(frames:List[Image.Image],*,include_instruction:bool)-Dict:payload{session_id:session_id,images_base64:[_pil_to_data_url(im,codecimage_codec)foriminframes],prefix_mode:False,# 增量协议allow_future_segments:True,# 允许提前输出动作action_head_mode:tsformer_latent,}ifinclude_instruction:payload[instruction]instruction payload[reset_session]True# 首轮强制新建 sessionreturn_http_post_json(url/v1/predict_delta_actions,payload)# 闭环主循环im0capture_first_frame()resp_post_frames([im0],include_instructionTrue)# 第 1 帧 instructionforsegmentinrange(num_segments):actionsresp[actions]# 16 个 [dx,dy,dz,droll,dyaw,dpitch]new_framesexecute_and_capture(actions)# 执行动作采集 16 帧真实图像resp_post_frames(new_frames,include_instructionFalse)# 回传真实帧客户端输出的 JSON 格式# infer/client.py: 每个 segment 输出两个文件# 1. {session_id}_seg00_actions.json{session_id:route_001,segment_index:0,units:{translation:cm,angles:deg},action_order_server:[dx,dy,dz,droll,dyaw,dpitch],actions_server_order:[[1.2,-0.3,0.5,0.0,2.1,-0.1],...],# 16 个cumsum_server_order:[[1.2,-0.3,0.5,0.0,2.1,-0.1],...],# 累加}# 2. {session_id}_seg00_poses.json (绝对坐标)6.3 TrajectoryState闭环的最低条件TrajectoryState对应单条 session 的闭环状态。它保存已收到的真实帧、prompt、streaming session以及跨 segment 复用的last_latent_1。…详情请参照古月居
延伸阅读

更多相关文章

2026/10/25 1:47:01

基于BP神经网络与MFCC特征的猪咳嗽声识别系统构建与部署实践

简介:本资源是基于MATLAB实现的猪咳嗽声智能识别项目,面向农业物联网、动物健康监测领域的初学者与工程实践者,解决生猪养殖中呼吸道疾病早期预警的关键问题——通过BP神经网络对咳嗽声、哼哼声、咆哮声等典型猪只音频进行多类别分类。压缩包…

2026/10/23 18:37:24

TVA-World架构:具身智能全栈算法研究新突破(2)

前沿技术探索:TVA智能体(简称TVA)TVA智能体(亦称“AI智能体视觉”或“TVA视觉智能体”)是依托Transformer架构与“因式智能体”理论构建的通用视觉技术体系。它有机融合深度强化学习(DRL)、卷积…

2026/10/25 11:13:53

基于FEKO仿真数据的距离-多普勒ISAR成像流程与关键参数解析

简介:面向雷达成像与电磁散射方向工程师和研究生的二维ISAR成像资源,结合FEKO仿真建模与MATLAB处理,用于解决目标高分辨率成像及回波数据分析问题。资源包共7个文件,压缩包仅50KB,包含4个txt数据或说明文本与3个m格式M…

2026/10/25 11:13:53

多无人机编队控制:Voronoi图与人工势场Matlab仿真实现

上个月课题组仿真环境里出现了一个经典画面:8架无人机在空旷场地上排成整齐队形,可一旦场地中央放上一根圆柱障碍物,编队在绕行后迟迟恢复不了,还有几架在障碍物背后反复绕圈。后来我把整个控制框架换成了多智能体分布式方案——用…

2026/10/25 11:13:53

Proficy Historian API 从入门到落地:读数据、写回与定时采集

简介:面向 C# 开发者的 Proficy Historian API 二次开发示例工程,覆盖数据采集、写入、报警事件管理、可视化及导入导出等常见需求,帮助首次接触该接口的开发者解决缺少可参照项目的问题。压缩包共 18 个文件,约 18KB,…

2026/10/25 11:13:53

时序Transformer实战:电力负荷与股价预测源码解析

简介:本资源是一套基于Transformer架构实现时间序列预测的Python完整源码项目,面向机器学习初学者与课程设计学生,尤其适合作为期末大作业或AI实践入门参考。项目代码经过本地编译验证,运行稳定,难度适中,涵…

2026/10/25 11:08:52

text-to-CAD工程实践:从文字到STEP的可靠建模方法

1. 这不是“AI画图”,而是让文字真正长出几何体的工程级跃迁最近在几个机械设计群和工业软件论坛里,反复看到有人发截图:一段英文描述“带M6螺纹孔的铝制支架,长120mm,宽60mm,厚8mm,底部有4个Φ…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/25 0:02:22

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/25 0:02:23

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/25 0:02:23

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑