拿到 LingBot-VA 2.0 之后,不建议第一条命令就连真机。更稳妥的顺序是:在仿真环境里固定一份观测输入,调用一次推理并打印输出结构,确认返回的是单步动作还是动作序列、维度能不能被仿真器直接消费,再把单步耗时和重复运行的一致性记下来。这几步都过了,才有讨论真机接入的前提;任何一步没过,接硬件的风险都不在模型本身,而在接口契约没对齐。
判断方向:LingBot-VA 2.0 是否可用于当前真机,先看仿真里的单步推理能否稳定复现。适用场景:刚拿到模型、尚未确认输入输出契约。操作动作:固定一份观测输入落盘成文件,用最小脚本调一次推理,打印 shape 与 dtype,再核对动作维度与仿真器接口。验证方式:重复运行看输出与耗时是否漂移。风险边界:仿真跑通不等于真机可用,限幅、急停、人工接管没补齐前不要接硬件。
在仿真环境里准备一份可复现的观测输入
如果每次验证都重新采一遍现场数据,结论会跟着环境漂移,很难判断是模型问题还是输入问题。建议先把某一步的观测单独落盘成文件,之后所有验证都读这一份。
需要先确认三件事:字段来源(哪些来自仿真器状态、哪些来自渲染图像、哪些来自上一帧动作)、采样频率(与仿真步长是否一致,是否需要插值或抽帧)、以及落盘格式。不绑定具体接口名,通用的骨架大致如下:
obs_step_00001.json # 元信息:时间戳、步序号、字段清单
obs_step_00001.npz # 数值数组:图像帧、关节或位姿状态、上一步动作
# json 骨架(字段名按实际仿真器替换)
{
"step": 1,
"dt_sec": ...,
"fields": ["image", "proprio", "last_action"],
"shapes": {"image": [..., ...], "proprio": [...], "last_action": [...]}
}落盘后先自己读回来一次,确认数组没有被压缩、转置或截断。这一步的成本很低,但能省掉后面大量“到底是模型错还是加载错”的排查。
用最小脚本调用一次推理并打印输出结构
不要一上来就接控制循环。先用一条观测跑一次推理,把返回内容的类型、形状、数据类型全部打印出来,看清楚是单步动作还是长度为 N 的动作序列。
import numpy as np
obs = load_obs("obs_step_00001.npz") # 替换成自己的加载函数
print({k: (np.asarray(v).shape, np.asarray(v).dtype) for k, v in obs.items()})
out = policy.infer(obs) # 调用入口以实际 SDK 为准
print("type:", type(out))
print("raw:", out)
if isinstance(out, dict):
for k, v in out.items():
a = np.asarray(v)
print(k, "shape=", a.shape, "dtype=", a.dtype, "min_max=", (a.min(), a.max()))
else:
a = np.asarray(out)
print("shape=", a.shape, "dtype=", a.dtype)打印之外,建议同时看运行日志:日志里通常会记录实际调用的入口名、批次维度有没有被补上、有没有被自动裁剪或截断。页面或日志显示的返回结构,比文档描述更可信。
核对动作维度与仿真器可接受的执行接口
模型输出的形状和仿真器能吃的形状,经常差一维或差一个通道顺序。核对时按这个顺序查:
- 维度数量:仿真器期望一维动作向量还是 [T, D] 序列;D 与仿真器自由度是否一致。
- 批次维:单步推理是否多出一个 batch 维度,需不需要 squeeze。
- 顺序与符号:关节顺序、旋转表示(欧拉角/四元数/旋转矩阵)、坐标系方向是否一致。
- 单位与取值范围:位置单位是米还是厘米,角度是弧度还是度,归一化动作还是有量纲动作,先看一次输出里的最小值和最大值落在什么区间。
- 时序语义:输出是绝对目标还是相对增量,是否需要叠加到当前状态上。
不匹配时通常不会静默成功,典型报错长这样(措辞随框架不同):“shape mismatch: expected (…, D) got (…, D')”“cannot reshape array of size …”“index out of range”,或者仿真器直接抛参数校验失败。看到这类报错,先回到形状和单位,不要急着改模型。
记录单步耗时与重复运行的一致性
单步能跑通只说明调用链没断,不代表能放进控制循环。建议对同一份观测重复跑若干次,观察输出是否逐次一致、耗时是否抖动明显。
计时点建议放在推理调用前后,而不是整个脚本前后,避免把加载和落盘时间算进去。记录字段至少包括:运行序号、输出形状与 dtype、输出是否与首次完全一致、单步耗时、以及出现异常时的日志行号。
| run | shape | dtype | 与首次一致 | 耗时 | 备注 |
|---|---|---|---|---|---|
| 1 | 基准 | ||||
| 2 | |||||
| 3 |
如果多次结果不一致,先确认是否存在随机采样或未固定的种子;如果耗时波动很大,先排除首次加载、显存换页和日志刷盘这些干扰项,再判断是否满足控制频率要求。
列出接真机前必须补上的安全与限速项
仿真结论不能直接搬到硬件上。接真机之前,至少要把下面三类前置条件逐条核对清楚,缺一项就先不接:
- 动作限幅:在仿真输出到真实指令之间加一层裁剪,明确每一维的上下限、速度上限和加速度上限;限幅规则要能被日志记录,便于回溯。
- 急停通路:确认存在独立于模型的停止手段,按下后能切断指令下发;同时确认通信中断、超时、返回值异常时的默认行为是停在原地而不是继续执行上一条指令。
- 人工接管:明确谁在什么条件下接管,接管后模型输出如何被忽略,恢复流程是什么;接管开关不要和急停混用同一个按钮。
这三项建议先在仿真里模拟异常路径跑一遍:注入一次越界动作、模拟一次通信超时、手动触发一次接管,看系统行为是否符合预期。仿真里跑通不等于真机安全,但仿真里没跑通的保护逻辑,不要指望上硬件就自动生效。