WALL-OSS (WALL-X) 模型架构

1. 整体架构概览

WALL-OSS (WALL-X) 是一个跨具身的 视觉-语言-动作 (VLA) 模型,以 Qwen2.5-VL + 混合专家 (MoE) 作为视觉语言骨干网络,结合 Flow Matching 动作头 进行机器人连续动作预测。与 GR00T N1.5 等模型不同,WALL-X 采用当前最强的 VLM (Qwen2.5-VL) 作为骨干,通过 3D RoPE 位置编码对图像/视频的时空维度建模,并使用 MoE 路由机制将动作 token 和语言 token 分流至不同的专家网络。模型支持三种推理模式:纯文本自回归生成 (Text)、离散动作 token 快速生成 (Fast)、以及基于 ODE 积分的连续扩散动作预测 (Diffusion)。

graph TB subgraph Input["输入"] IMG["相机图像
(pixel_values)
支持多视角"] VID["视频帧
(pixel_values_videos)
可选"] TXT["语言指令
(input_ids)"] STATE["本体感知状态
[B, n_obs, state_dim]"] DOF["自由度掩码
(dof_mask / agent_pos_mask)"] end subgraph Backbone["Qwen2.5-VL MoE 骨干网络"] VE["视觉编码器
(Qwen2_5_VisionTransformer)
3D Conv + ViT"] PM["Patch Merger
(空间合并)"] EMB["Token Embedding
(embed_tokens)"] ROPE["3D RoPE
(时间-高度-宽度)"] MOE["MoE Decoder Layers
(SparseMoeBlock)
语言/动作 token 分流"] LMH["语言模型头
(lm_head)"] end subgraph ActionHead["Flow Matching 动作头"] PP["本体感知投影
(propri_proj)"] AH["动作编码网络
w1 -> w2 -> SiLU -> w3"] TE["正弦时间步嵌入
(SinusoidalPosEmb)"] FM["Flow Matching
噪声 + Beta(1.5,1.0) 时间步"] APB["动作投影回映
(action_proj_back)"] end subgraph Output["输出"] ACT["预测动作轨迹
[B, chunk_size, action_dim]"] TEXT_OUT["文本输出
(自回归生成)"] end IMG --> VE VID --> VE VE --> PM --> EMB TXT --> EMB EMB --> ROPE --> MOE STATE --> PP DOF --> PP DOF --> AH PP -->|"本体感知嵌入
替换 propri token"| MOE FM --> AH TE --> AH AH -->|"动作嵌入
替换 action token"| MOE MOE --> LMH --> TEXT_OUT MOE -->|"动作位置 hidden_states"| APB --> ACT style Input fill:#e8f4fd,stroke:#2196F3 style Backbone fill:#fff3e0,stroke:#FF9800 style ActionHead fill:#e8f5e9,stroke:#4CAF50 style Output fill:#fce4ec,stroke:#E91E63

2. 核心组件详解

2.1 Qwen2.5-VL MoE 视觉语言骨干网络

WALL-X 采用 Qwen2.5-VL 作为视觉语言骨干网络,并在其基础上引入 MoE (混合专家) 机制。这是目前 VLA 领域使用的最强 VLM 骨干之一。整体模型由三部分组成:视觉编码器、Patch Merger 空间合并层、以及带 MoE 的 Decoder 层。

graph LR subgraph VisionEncoder["① 视觉编码器 (Qwen2_5_VisionTransformer)"] PIX["pixel_values
[B, C, T, H, W]"] --> CONV3D["3D Conv Patch Embed
kernel=[temp_patch, 14, 14]
in=3, out=hidden"] CONV3D --> VIT["ViT Transformer Blocks
depth=32 层
全局注意力: Layer 7,15,23,31"] VIT --> PMERGE["PatchMerger
spatial_merge_size=2
RMSNorm -> MLP"] end subgraph TokenEmbed["② Token Embedding"] IDS["input_ids"] --> EMB["nn.Embedding
(vocab_size, hidden_size)"] EMB --> MERGE["图像/视频 token 位置
替换为视觉特征"] end subgraph MoEDecoder["③ MoE Decoder (Qwen2_5_VLMoEModel)"] MERGE --> LAYERS["N 层 Decoder Layer with MoE
Self-Attention + MoE/MLP"] LAYERS --> NORM["RMSNorm"] NORM --> OUT["hidden_states"] end PMERGE -->|"视觉特征
[N_patches, hidden]"| MERGE style VisionEncoder fill:#e3f2fd,stroke:#2196F3 style TokenEmbed fill:#f3e5f5,stroke:#9C27B0 style MoEDecoder fill:#e8f5e9,stroke:#4CAF50

关键设计: - 视觉编码器使用 3D 卷积 进行 Patch Embedding,kernel_size = [temporal_patch_size, patch_size, patch_size],天然支持视频时序输入 - ViT 中的全局注意力层位于第 7、15、23、31 层,其余层使用窗口注意力 (window_size=112) - Patch Merger 通过 spatial_merge_size=2 将空间分辨率降为原来的 1/4,减少送入 LLM 的 token 数 - Decoder 的每一层都是 Qwen2_5_VLDecoderLayer_with_MoE,根据配置选择使用标准 MLP 或 SparseMoeBlock

2.2 3D RoPE 位置编码 (时间-高度-宽度)

WALL-X 使用 3D 旋转位置编码 (3D RoPE / mRoPE),为视觉 token 计算三维 (时间-高度-宽度) 位置 ID,为文本 token 使用标准 1D 位置编码。这使得模型能够感知图像/视频的空间和时序结构。

graph TB subgraph InputTokens["输入序列"] T1["文本 token
(1D 位置)"] I1[""] I2["图像/视频 token
(3D 位置)"] I3[""] T2["文本 token
(1D 位置, 延续)"] A1["动作 token
(1D 位置)"] end subgraph RoPE3D["3D RoPE 位置计算 (get_rope_index)"] direction TB FIND["查找 vision_start_token_id
识别图像/视频区间"] FIND --> GRID["获取 grid_thw
[temporal, height, width]"] GRID --> SPATIAL["空间合并
h' = h/merge_size
w' = w/merge_size"] subgraph PosCalc["3D 位置 ID 计算"] T_IDX["时间轴 t_index
= t * second_per_grid
* tokens_per_second"] H_IDX["高度轴 h_index
= arange(h')"] W_IDX["宽度轴 w_index
= arange(w')"] end SPATIAL --> PosCalc PosCalc --> STACK["stack([t_index, h_index, w_index])
→ position_ids [3, B, seq_len]"] end subgraph Output["输出"] POS["position_ids
[3, B, seq_len]
3 个通道分别对应
时间/高度/宽度"] DELTA["mrope_position_deltas
[B, 1]"] end InputTokens --> RoPE3D STACK --> POS STACK --> DELTA style InputTokens fill:#fff3e0,stroke:#FF9800 style RoPE3D fill:#e8f5e9,stroke:#4CAF50 style PosCalc fill:#e3f2fd,stroke:#2196F3 style Output fill:#fce4ec,stroke:#E91E63

核心逻辑 (源码 get_rope_index): 1. 遍历输入序列,找到每个 vision_start_token_id 标记的起始位置 2. 根据 image_grid_thwvideo_grid_thw 获取该图像/视频的 [T, H, W] 网格尺寸 3. 经过 spatial_merge_size 合并后,计算 [llm_grid_t, llm_grid_h, llm_grid_w] 4. 对每个视觉 token 生成 3D 位置 ID:t_index 考虑了 second_per_grid_t * tokens_per_second 的时间缩放 5. 文本 token 使用标准 1D 递增位置(三个通道值相同),从视觉 token 最大位置 +1 延续

2.3 MoE (混合专家) 路由机制

WALL-X 的关键创新之一是在 Decoder 层中引入 MoE 路由,将 语言 token动作 token 分流到不同的专家网络进行处理。路由信号由 moe_token_types 控制,该标记根据 <|action|> token 的位置自动生成。

graph TB subgraph Router["MoE 路由机制"] direction TB INPUT["hidden_states
[B, seq_len, hidden_dim]"] TYPES["moe_token_types
(0=语言, 1=动作)"] end subgraph DecoderLayer["Qwen2_5_VLDecoderLayer_with_MoE"] LN1["Input LayerNorm
(RMSNorm)"] SA["Self-Attention
(共享, 所有 token)"] RES1["+ 残差连接"] LN2["Post-Attention LayerNorm
(RMSNorm)"] subgraph MoEBlock["SparseMoeBlock"] direction LR ROUTE["按 expert_indices 路由"] subgraph Expert0["Expert 0 (语言)"] E0["BlockSparseMLP
gate_proj -> act -> up_proj
-> down_proj"] end subgraph Expert1["Expert 1 (动作)"] E1["BlockSparseMLP
gate_proj -> act -> up_proj
-> down_proj"] end ROUTE -->|"token_type=0"| E0 ROUTE -->|"token_type=1"| E1 end RES2["+ 残差连接"] end INPUT --> LN1 --> SA --> RES1 --> LN2 TYPES --> ROUTE LN2 --> MoEBlock --> RES2 RES2 --> OUT["输出 hidden_states"] style Router fill:#e8f4fd,stroke:#2196F3 style DecoderLayer fill:#fff3e0,stroke:#FF9800 style MoEBlock fill:#e8f5e9,stroke:#4CAF50 style Expert0 fill:#e3f2fd,stroke:#2196F3 style Expert1 fill:#fce4ec,stroke:#E91E63

路由细节: - moe_token_types 在数据预处理阶段根据 input_ids == action_token_id 自动生成 - SparseMoeBlock 包含多个 BlockSparseMLP 专家,每个专家有独立的 gate_projup_projdown_proj - 每个专家可以有不同的 dim_inputs(输入维度),由配置中的 dim_inputs 元组指定 - Self-Attention 在所有 token 间共享(不分流),仅 FFN 层通过 MoE 分流 - 当 config.mlp_moe=False 时,退化为标准 MLP(无 MoE),保持与原始 Qwen2.5-VL 兼容

2.4 Flow Matching 动作头

Flow Matching 动作头 (ActionHead) 是 WALL-X 的动作预测核心,使用 Beta 分布时间步采样和正弦时间步嵌入实现连续动作空间的流匹配预测。

graph TB subgraph Training["训练阶段 (forward)"] direction TB ACT["action_chunk
[B, chunk_size, action_dim]"] DMASK["dof_mask
[B, chunk_size, action_dim]"] subgraph NoiseSchedule["噪声调度"] BETA["t ~ Beta(1.5, 1.0)
time = (1-t) * 0.999"] NOISE["noise ~ N(0, 1)"] INTERP["noisy_action = (1-t)*noise + t*action"] FLOW["flow_target = action - noise"] end subgraph ActionEmbed["动作嵌入网络"] CAT1["concat[noisy_action, dof_mask]
[B, T, action_dim*2]"] W1["w1: Linear(action_dim*2, hidden)
(无 bias)"] TIME["SinusoidalPosEmb(t)
→ time_embed"] CAT2["concat[action_embed, time_embed]
[B, T, hidden*2]"] W2["w2: Linear(hidden*2, hidden)
(无 bias)"] SILU["SiLU 激活"] W3["w3: Linear(hidden, hidden)
(无 bias)"] end ACT --> NoiseSchedule NoiseSchedule --> CAT1 DMASK --> CAT1 CAT1 --> W1 BETA --> TIME W1 --> CAT2 TIME --> CAT2 CAT2 --> W2 --> SILU --> W3 W3 --> EMB_OUT["action_embeddings
(替换 action token 位置)"] FLOW --> FLOW_OUT["flow_target
(监督信号)"] end subgraph Loss["损失计算"] HIDDEN["action 位置的 hidden_states
(经过 MoE Decoder)"] PROJ["action_proj_back
Linear(hidden, action_dim)"] MSE["MSE Loss
(带 dof_mask 加权)"] HIDDEN --> PROJ --> MSE FLOW_OUT --> MSE end style Training fill:#e8f5e9,stroke:#4CAF50 style NoiseSchedule fill:#fff3e0,stroke:#FF9800 style ActionEmbed fill:#e3f2fd,stroke:#2196F3 style Loss fill:#fce4ec,stroke:#E91E63

动作嵌入网络的计算公式:

action_embed = w3( SiLU( w2( concat[ w1(concat[noisy_action, dof_mask]), time_embed ] ) ) )

2.5 本体感知投影 (Proprioception + DOF Mask)

本体感知数据(关节位置、姿态等)通过 propri_proj 投影至隐藏空间,并替换序列中 <|propri|> token 的位置。DOF Mask 用于标记哪些自由度是有效的(跨具身统一维度)。

graph LR subgraph Input["输入"] PROP["proprioception
[B, n_obs, state_dim]"] AMASK["agent_pos_mask
[B, n_obs, state_dim]
(NaN 位置为 0)"] end subgraph Padding["维度填充 (至 max_state_dim=20)"] PAD["state_dim < 20 时
零填充至 [B, n_obs, 20]"] end subgraph Projection["投影"] CAT["concat[proprioception, mask]
[B, n_obs, 40]"] PROJ["propri_proj
Linear(propri_dim*2, hidden_size)
(无 bias)"] end subgraph Replace["Token 替换"] TOKEN["找到 propri_token_id
在 input_ids 中的位置"] SCATTER["masked_scatter:
inputs_embeds[propri_mask] = proprio_embed"] end PROP --> PAD --> CAT AMASK --> PAD PAD --> CAT --> PROJ --> Replace style Input fill:#e8f4fd,stroke:#2196F3 style Padding fill:#fff3e0,stroke:#FF9800 style Projection fill:#e8f5e9,stroke:#4CAF50 style Replace fill:#fce4ec,stroke:#E91E63

关键点: - 本体感知状态和动作都统一填充到 max_state_dim=20 / max_action_dim=20,使用 NaN 标记无效维度 - DOF Mask 自动从 NaN 位置推导:(~torch.isnan(data)).float() - propri_proj 输入维度为 propri_dim * 2(状态 + 掩码拼接),输出维度为 hidden_size - 动作的 DOF Mask 同理,在 w1 中与 noisy_action 拼接:w1(concat[noisy_action, dof_mask])


3. 三种推理模式

3.1 Text 模式 (纯自回归文本生成)

Text 模式下,模型作为标准 VLM 使用,通过自回归方式逐 token 生成文本回复。此模式不涉及动作预测,仅用于语言理解和生成任务。

graph LR subgraph Input["输入准备"] IMG["图像"] --> VE["视觉编码"] TXT["文本指令
+ <|im_start|>assistant"] --> TOK["Tokenize"] VE --> EMB["嵌入融合"] TOK --> EMB PROP["本体感知"] --> PP["propri_proj"] --> EMB end subgraph Split["序列分割"] EMB --> FIND["查找 <|im_start|>assistant
分割点"] FIND --> PROMPT["保留 prompt 部分
(input_ids[:split+3])"] FIND --> GT["提取 GT 输出
(input_ids[split+3:])"] end subgraph Generate["自回归生成"] PROMPT --> GEN["model.generate()
max_new_tokens=100
temperature=1.0
do_sample=False"] GEN --> DEC["batch_decode()
解码为文本"] end subgraph Output["输出"] DEC --> PRED["predict_output_text"] GT --> GT_TEXT["gt_output_text"] end style Input fill:#e3f2fd,stroke:#2196F3 style Split fill:#fff3e0,stroke:#FF9800 style Generate fill:#e8f5e9,stroke:#4CAF50 style Output fill:#fce4ec,stroke:#E91E63

注意: Text 模式仅支持 batch_size=1

3.2 Fast 模式 (离散动作 token 生成)

Fast 模式将连续动作离散化为 token,通过自回归方式快速生成动作 token 序列,然后解码为连续动作。需要配合 action_tokenizer(如 physical-intelligence/fast)使用。

graph LR subgraph Input["输入准备"] IMG["图像"] --> VE["视觉编码"] TXT["文本指令"] --> TOK["Tokenize
(含 action_token)"] VE --> EMB["嵌入融合"] TOK --> EMB end subgraph Generate["自回归生成"] EMB --> SPLIT["分割 prompt/gt"] SPLIT --> GEN["model.generate()
max_new_tokens=100"] GEN --> IDS["predict_output_ids"] end subgraph Decode["动作解码"] IDS --> FILTER["提取 action_token
(id >= action_token_start_index)"] FILTER --> OFFSET["减去 start_index 偏移"] OFFSET --> DEC["action_processor.decode()
time_horizon, action_dim"] DEC --> UNMASK["应用 dof_mask
取有效维度"] end subgraph Output["输出"] UNMASK --> ACT["predict_action
[B, chunk_size, action_dim']"] end style Input fill:#e3f2fd,stroke:#2196F3 style Generate fill:#fff3e0,stroke:#FF9800 style Decode fill:#e8f5e9,stroke:#4CAF50 style Output fill:#fce4ec,stroke:#E91E63

Fast 模式要点: - 使用 use_fast_tokenizer=True,需预加载 action tokenizer(默认 physical-intelligence/fast) - 生成的 token 中,ID >= action_token_start_index 的 token 为动作 token - 通过 action_processor.decode() 将离散 token 序列解码回连续动作空间 - 仅支持 batch_size=1

3.3 Diffusion 模式 (ODE 积分连续动作预测)

Diffusion 模式是 WALL-X 最核心的推理模式。从随机高斯噪声出发,通过 ODE 欧拉积分迭代去噪,最终得到连续动作轨迹。此模式支持任意 batch size。

graph TB subgraph Init["初始化"] NOISE["noisy_action ~ N(0, 1)
[B, pred_horizon, action_dim]"] TIMES["时间步: linspace(0, 1, N+1)
默认 N=10"] end subgraph EulerLoop["ODE 欧拉积分循环 (odeint)"] subgraph Step["单步去噪 (step 函数)"] direction TB NA["noisy_action_t"] --> AH_STEP["action_preprocessor.step()
concat[noisy, dof_mask] -> w1
+ time_embed -> w2 -> SiLU -> w3"] AH_STEP --> REPLACE["替换 inputs_embeds 中
action token 位置"] REPLACE --> TRANS["完整 Transformer 前向传播
self.model(inputs_embeds=...)"] TRANS --> EXTRACT["提取 action 位置的
hidden_states"] EXTRACT --> PROJ["action_proj_back
Linear(hidden, action_dim)"] PROJ --> VELOCITY["预测速度 v"] end T0["t=0: step(t, noise) -> v0
action_1 = noise + dt*v0"] T1["t=dt: step(t, action_1) -> v1
action_2 = action_1 + dt*v1"] TDOTS["..."] TN["t=1-dt: step(t, action_N-1) -> vN
action_N = action_N-1 + dt*vN"] T0 --> T1 --> TDOTS --> TN end subgraph Output["输出"] TN --> FINAL["action_trajectory[-1]
最终预测动作
[B, pred_horizon, action_dim]"] end NOISE --> T0 TIMES --> EulerLoop style Init fill:#e3f2fd,stroke:#2196F3 style EulerLoop fill:#e8f5e9,stroke:#4CAF50 style Step fill:#fff3e0,stroke:#FF9800 style Output fill:#fce4ec,stroke:#E91E63

ODE 积分细节 -- 单步展开:

graph LR AT["action_t
(当前含噪动作)"] --> CONCAT["concat[action_t, dof_mask]"] CONCAT --> W1_S["w1 投影"] TS["timestep t"] --> TE_S["SinusoidalPosEmb"] TE_S --> CAT_S["concat[action_embed, time_embed]"] W1_S --> CAT_S CAT_S --> W2_S["w2 -> SiLU -> w3"] W2_S --> EMBED["动作嵌入 → 替换 action token"] EMBED --> TRANS_S["Transformer 前向"] VL["已编码的视觉语言特征
(首次计算后复用)"] --> TRANS_S TRANS_S --> HS["action hidden_states"] HS --> PROJ_S["action_proj_back → 速度 v"] AT --> EULER["action_{t+1} = action_t + dt * v"] PROJ_S --> EULER EULER --> AT1["action_{t+1}"] style TRANS_S fill:#e8f5e9,stroke:#4CAF50 style EULER fill:#fff9c4,stroke:#FFC107

注意: 每一步去噪都需要完整的 Transformer 前向传播(因为需要与视觉语言 token 进行注意力交互)。默认 num_inference_timesteps=10


4. 训练流水线

graph LR subgraph VisionEncoder["① 视觉编码器 (Qwen2_5_VisionTransformer)"] PIX["pixel_values
[B, C, T, H, W]"] --> CONV3D["3D Conv Patch Embed
kernel=[temp_patch, 14, 14]
in=3, out=hidden"] CONV3D --> VIT["ViT Transformer Blocks
depth=32 层
全局注意力: Layer 7,15,23,31"] VIT --> PMERGE["PatchMerger
spatial_merge_size=2
RMSNorm -> MLP"] end subgraph TokenEmbed["② Token Embedding"] IDS["input_ids"] --> EMB["nn.Embedding
(vocab_size, hidden_size)"] EMB --> MERGE["图像/视频 token 位置
替换为视觉特征"] end subgraph MoEDecoder["③ MoE Decoder (Qwen2_5_VLMoEModel)"] MERGE --> LAYERS["N 层 Decoder Layer with MoE
Self-Attention + MoE/MLP"] LAYERS --> NORM["RMSNorm"] NORM --> OUT["hidden_states"] end PMERGE -->|"视觉特征
[N_patches, hidden]"| MERGE style VisionEncoder fill:#e3f2fd,stroke:#2196F3 style TokenEmbed fill:#f3e5f5,stroke:#9C27B0 style MoEDecoder fill:#e8f5e9,stroke:#4CAF50
0

训练损失公式:

L_total = L_cross_entropy + flow_loss_weight * L_flow

L_cross_entropy = CE(shift_logits, shift_labels)   # 忽略 label=-100 的位置
L_flow = MSE(action_proj_back(h_action), flow_target) * dof_mask   # 仅在有效 DOF 上计算

其中 flow_target = action_chunk - noiseh_action 是 action token 位置的 Transformer 隐藏状态。


5. 关键超参数表

参数 说明
chunk_size 32 动作预测时域长度 (action horizon)
n_action_steps 32 每次推理使用的动作步数
max_action_dim 20 跨具身统一动作维度
max_state_dim 20 跨具身统一状态维度
n_obs_steps 1 观测历史步数
prediction_mode "diffusion" / "fast" 推理模式选择
num_inference_timesteps 10 Diffusion 模式去噪步数
beta_alpha 1.5 Flow Matching Beta 分布 alpha
beta_beta 1.0 Flow Matching Beta 分布 beta
s (时间上界) 0.999 采样时间缩放因子
flow_loss_weight 1.0 Flow Loss 权重系数
RESOLUTION 256 输入图像分辨率
IMAGE_FACTOR 28 Patch 对齐因子
MIN_PIXELS 4 * 28 * 28 最小像素数
MAX_PIXELS 16384 * 28 * 28 最大像素数
TOKENIZER_MAX_LENGTH 768 Tokenizer 最大长度
num_experts 4 (默认) MoE 专家数量
spatial_merge_size 2 视觉 Patch 空间合并系数
patch_size 14 视觉 Patch 大小
temporal_patch_size 2 时间维度 Patch 大小
vision_depth 32 视觉 Transformer 层数
fullatt_block_indexes [7, 15, 23, 31] 全局注意力层索引
optimizer_lr 2e-5 学习率
optimizer_betas (0.9, 0.95) Adam beta 参数
optimizer_weight_decay 0.01 权重衰减
optimizer_grad_clip_norm 1.0 梯度裁剪
scheduler_warmup_steps 1000 预热步数
scheduler_decay_steps 100000 衰减步数
LoRA r 8 (默认) LoRA 秩
LoRA target_modules ["q_proj", "v_proj"] LoRA 目标模块

6. 关键源文件表

组件 类名 文件路径
策略封装 WallXPolicy lerobot/policies/wall_x/modeling_wall_x.py:1689
主模型 Qwen2_5_VLMoEForAction lerobot/policies/wall_x/modeling_wall_x.py:256
Flow Matching 动作头 ActionHead lerobot/policies/wall_x/modeling_wall_x.py:109
正弦位置嵌入 SinusoidalPosEmb lerobot/policies/wall_x/modeling_wall_x.py:92
MoE Decoder 模型 Qwen2_5_VLMoEModel lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:2360
MoE Decoder 层 Qwen2_5_VLDecoderLayer_with_MoE lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:2265
稀疏 MoE 模块 SparseMoeBlock lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:2217
专家 MLP BlockSparseMLP lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:2201
视觉 Transformer Qwen2_5_VisionTransformerPretrainedModel lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py
Patch Embedding Qwen2_5_VisionPatchEmbed lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:68
Patch Merger Qwen2_5_VLPatchMerger lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:136
模型输出定义 Qwen2_5_VLACausalLMOutputWithPast lerobot/policies/wall_x/qwen_model/qwen2_5_vl_moe.py:2187
Qwen VL 配置 Qwen2_5_VLConfig lerobot/policies/wall_x/qwen_model/configuration_qwen2_5_vl.py:43
视觉编码器配置 Qwen2_5_VLVisionConfig lerobot/policies/wall_x/qwen_model/configuration_qwen2_5_vl.py:5
策略配置 WallXConfig lerobot/policies/wall_x/configuration_wall_x.py:26
常量定义 -- lerobot/policies/wall_x/constant.py
工具函数 get_wallx_normal_text, replace_action_token lerobot/policies/wall_x/utils.py