第 3 周(2026-07-20 ~ 2026-07-24)
宋红 · AgentOS 编排层 / SimCar 端侧探索 阶段声明:端侧 SimCar 从单句指令推进到多轮对话上下文,补齐规划基准与实时语音闭环,并按老板要求启动 Ascend 310B 端侧 SenseVoice 部署
一、本周目标
承接上周端侧 SimCar 复合任务 MVP,把“单句指令能跑”推进到“多轮场景能接、计划质量可量化、离线也能演示、语音入口可闭环”,并按老板明确要求启动 Ascend 310B / Orange Pi AIpro 20T 上的 SenseVoice 端侧部署。
| 目标 | 对应工作 | 本周结果 |
|---|---|---|
| 收敛 L1 基础动作稳定性 | 确定性快速路径,规避 1.5B 在温度 0 下的漂移与畸形 JSON | ✅ 已完成并通过回归 |
| 打通多轮对话上下文 | 有界会话记忆 + 安全指代补全 + 纯观察话轮 | ✅ 已实现并通过真实链路验证 |
| 建立规划质量与安全门禁 | 36 条中文规划基准,区分 raw / final 与 demo / model 门禁 | ✅ 已建立基准并给出门禁结论 |
| 补齐离线可演示能力 | SIMCAR_REHEARSAL=1 端侧预演模式 | ✅ 已落地并通过契约测试 |
| 接通实时语音入口 | WSLg 实时麦克风采集与虚拟麦克风回放闭环 | ✅ 本机链路已跑通并留证据 |
| 启动 310B 端侧部署 | Orange Pi AIpro 20T / Ascend 310B1 上的 SenseVoice 迁移 | 🔄 板端已连通并盘点,ONNX 已导出;OM 转换阻塞在工具链算子包,持续推进中 |
二、关键成果
2.1 L1 确定性快速路径
上一周的整链验证暴露了一个真实问题:同一句“最大速度前进两秒”在 Qwen2.5-1.5B 温度为 0 时仍会漂移,一次输出正确移动,一次错误输出正方形计划。处理方式不是简单加重试,而是新增高置信 L1 快速路径:
- 方向和米/厘米/秒/角度均明确的基础动作,在调用 LLM 之前就确定性解析;
前进2米、最大速度前进2秒、左转90度、加速/减速不再依赖 LLM 服务是否可用;- 否定句、疑问句和包含“然后/循环/障碍/图形/捡球”等复合语义的句子不进入快速路径;
- L2-L4 抽象任务仍由本地 Qwen 做高层语义选择,再由白名单模板和 Gateway 校验收敛。
修正后,五条合成中文语音的“波形 → SenseVoice → 路由 → 结构化计划”结果为 5/5。
2.2 有界会话上下文与多轮连续避障
此前 UserRequest.session_id 只在响应中原样回传,没有参与路由或规划,第一轮场景陈述和第二轮动作指令彼此独立,“绕过去”缺少可靠的会话目标。本周新增 agent_api.dialogue_context.DialogueContextStore:
- 按
session_id隔离,只保存规范化障碍物目标,不保存音频和完整历史; - 10 分钟不活跃 TTL,最多 128 个会话,超限淘汰最旧状态;
- 超长
session_id使用 SHA-256 生成有界键,进程重启即清空,不伪装成持久地图或世界模型。
在此之上完成三件事:
- 安全指代补全:只补全“绕过去/绕过它/绕开它/避开它”这类明确绕障表达,不补全“把它捡起来”等可能指向球、瓶子或其他物体的歧义操作;路由使用补全后的
resolved_text,执行层仍收到用户原话,两者同时保留在ToolCall.arguments便于回放审计。 - 纯观察话轮:对“前面有个可乐瓶”这类只陈述场景、不含动作或问题的话轮,只记录场景事实,不调用 LLM、不调用 VLA/Gateway,返回
attempts=0并确定性回复“已记录前方的可乐瓶,本轮不执行动作”。 - 绕障前进收敛模板:将明确的“绕障 + 前进距离”收敛为
navigate_forward(distance_cm, side),用户明确左右时以原话为准,模型 JSON 合法时保留模型选择,畸形时用auto或用户侧向兜底,左右冲突/缺距离/带其他任务时不启用模板、继续安全拒绝。
真实 Agent API + Qwen2.5-1.5B + SimCar Gateway dry_run 两轮结果:
第一轮:
intent=llm.general_qa
provider=dialogue_context
attempts=0
answer=已记录前方的可乐瓶,本轮不执行动作。
第二轮:
resolved_text=从左边绕过可乐瓶,然后前进两米
intent=robot.execute_plan
plan=navigate_forward(distance_cm=200, side=left)
final_state=complete
边界判断(诚实口径):多轮对话只解决“同一会话内的绕障指代补全”,刻意不做跨会话共享、跨进程持久、歧义操作补全、把疑问句当场景事实。这样既能支撑连续话术演示,又不会因为过度记忆产生“我会去拿那个瓶子”这类口头承诺与实际行为不一致的风险。
2.3 Qwen2.5-1.5B 规划基准与安全预检门禁
为避免把模板兜底后的效果误报成小模型本身能力,新增 36 条中文规划基准,覆盖 L1 基础动作、L2 几何轨迹、L3 环境交互、L4 组合任务和 8 条安全样例,并分别统计模型原始 JSON 与端侧最终收敛结果:
raw: 18/36 = 50.0%
final: 36/36 = 100%
raw safety: 2/8 = 25.0%
final safety: 8/8 = 100%
guardrail rescues: 18
unsafe raw actions: 6
unsafe final actions: 0
raw model p95: 3.99s
final pipeline p95: 2.04s
warmup: 8.27s
门禁结论为 demo_gate_pass=true、model_gate_pass=false:当前 1.5B 只能在确定性数量落地、白名单模板和安全拒绝共同约束下支撑既定 Demo,不能表述为模型本身达到 GPT 级效果。这条结论是本周最重要的诚实口径。
统计口径判断:
- 把模型原始 JSON 与端侧收敛结果分开统计,是为了不把护栏救回来的 18 次误报成模型能力;
- 模型时延和端侧最终链路时延也分开报,避免把未调用模型的快速路径算进模型性能;
demo_gate_pass关心“既定 Demo 能否稳定跑通”,model_gate_pass关心“模型本身是否达标”;- 当前是前者通过、后者未通过,这决定了对外口径只能讲受约束的 Demo,不能讲模型效果;
- 这套统计口径也是后续对比 3B/7B 的基线。
2.4 端侧离线 rehearsal 模式
现有 dry_run 仍需读取真实 SimCar 状态,模拟器页面或 clientId 不可用时无法独立演示。新增显式 SIMCAR_REHEARSAL=1 模式:Gateway 使用固定 rehearsal fixture,只允许 dry_run=true,任何非预演请求直接返回 409,客户端控制方法也会抛错、不建立远端 SimCar 控制请求。
已在真实本地 Qwen2.5-1.5B、Agent API、Gateway 和 Judge 服务链验证:一米前进、左转 90 度、一米正方形、十次双转向循环、单障碍绕行前进两米,均生成完整有界命令且 final_state=complete,Judge 明确输出“SimCar dry-run 计划已生成,未执行动作”。
2.5 WSLg 实时麦克风与虚拟麦克风回放闭环
- 本机音频设备检查确认存在
RDPSource,parec --device=RDPSource --format=s16le --rate=16000 --channels=1连续采集 3 秒得到 71660 字节 PCM,证明 WSLg 音频穿透和 16kHz 单声道参数可用; - 新增持续采集、能量 VAD、预卷、静音结束、最长话轮限制和 WAV 生成,ASR 与普通动作执行分线程,停车类话术走独立高优先级 Agent 请求可抢占正在进行的普通动作;
- 为避免等待真人现场输入,临时创建 PulseAudio
SimCarMicnull sink 回放中文导航 WAV,Demo 脚本支持--source透传任意 source,真实输出:
[VAD] 话轮 1 已结束,正在识别
[ASR] 前进2米。
[执行] [SIMCAR] 复合任务预演完成
plan: navigate_forward(distance_cm=200, side=auto)
需诚实说明:当前是“持续采集 + VAD 整句话轮 + SenseVoice”,不是逐 token 流式 ASR;应用层急停也不替代硬件急停回路;虚拟麦克风回放不等价于真人声学环境。
2.6 测试证据
清理 __pycache__ 后的权威结果:
355 passed
10 skipped
1 个第三方 StarletteDeprecationWarning
新增覆盖包括:L1 确定性快速路径与否定/疑问/畸形输出回归、会话上下文隔离与 TTL、安全指代补全边界、纯观察话轮零动作、36 条规划基准数据集契约、rehearsal fixture 强制单障碍三航点绕行、VAD 预卷与静音切分、噪声不误触发。唯一警告来自 fastapi.testclient 对 Starlette/httpx 兼容层的第三方弃用提示,与本周代码无关。
2.7 Ascend 310B / SenseVoice 端侧部署(老板明确要求)
按老板要求,启动把 repos/voice-robot 的 SenseVoice 语音控制项目迁移到 Orange Pi AIpro 20T(Atlas 200I A2,Ascend 310B1)的工作,本周完成从零到板端连通、模型导出和工具链定位的第一阶段。
板端连通与盘点
- UART 确认为
COM3,115200 8N1可读到orangepiaipro-20t login:; - 电脑与板端均切到
Tsinghua-Dongsheng,电脑172.16.203.184、板端172.16.203.168,ping通(16-41ms),已建立HwHiAiUser@172.16.203.168的 SSH; - 板端:Ubuntu 22.04
aarch64,acl.get_soc_name()返回Ascend310B1,npu-smi25.2.0,NPU 内存 662/11577 MB;根分区 29GiB 已用 26GiB、仅剩约 2.1GiB,不适合在板端存原始模型或完整工具链;CANN 指向/usr/local/Ascend/cann-9.0.1,Python 3.10.12,amct_onnx0.23.2 可用; - 发现板端 ACLLite 应用缺
libacllite_common.so等三个库,现有 ResNet 示例未跑通,后续需补齐或改写为纯 AscendCL 后端。
本机导出环境与 ONNX
- 在 WSL2(Ubuntu 22.04,x86_64)建
/opt/ascend-sensevoice/venv,装齐torch 2.11.0+cpu/funasr 1.3.22/onnx 1.22.0/onnxruntime 1.23.2等 CPU 导出依赖; - 从 ModelScope 拉
iic/SenseVoiceSmall(原始model.pt约 936MB),导出 ONNX 基线图(输入speech/speech_lengths/language/textnorm,输出ctc_logits/encoder_out_lens); - 新导出器产生的 opset 18 图 CPU 推理成功,但 CANN 9.0.1 ATC 转换 segfault;改用传统导出器生成 opset 14 图(约 895MiB),已同步到板端
/tmp/sensevoice_ascend/model.onnx,两端 SHA256 一致。
OM 转换阻塞点定位(诚实口径)
- 官方公开容器只提供
9.0.1-310p-*,没有 310B 容器;该 310P 镜像 ATC 虽接受--soc_version=Ascend310B1,但选核阶段为大量LayerNorm和 FSMNConv2D报EZ3003 No supported Ops kernel and engine,不能产出可交付的 310B1 OM; - 早期 opset14 图曾被 ATC
Killed,排查确认是 Docker/WSL 编译 OOM,已把 WSL 内存扩到约 11GiB、Swap 8GiB,扩容后固定输入speech:1,100,560的图分析不再被杀; - 已确认板端自带的
/usr/local/Ascend/cann-9.0.1/opp含ascend310b的 Conv2D/LayerNorm 内核,因此改为直接在板端发起Ascend310B1、batch=1、T=100、FP16 的 ATC 编译,等待最终产出。
代码侧新增
- 新增
voice_robot/asr/ascend_backend.py:用 PyACL 执行 OM,CPU 侧实现官方 SenseVoice fbank(16kHz、80mel、25/10ms、LFR 7/6、am.mvnCMVN)和 SentencePiece/CTC 解码,新增--backend ascend及 OM/资源参数; - 前端与 FunASR
WavFrontend数值对齐已验证:同一音频 17 帧×560 特征平均绝对误差约1.6e-6(修正 PCM32768缩放后); - 新增
requirements-ascend.txt、scripts/setup_ascend_board.sh、scripts/run_ascend.sh和 README 的 310B 部署说明,原有 FunASR/RKNN 代码未删除。
当前判断:整套项目可部署在板端,阻塞点是模型转换工具包版本/产品包,不是目标板算力。首版坚持 FP16(先跑通再谈 INT8/INT4),不同时叠加工具链和精度两个变量。板端 ACLLite 缺库、根分区紧张、NPU 健康显示 Alarm 三项待后续处理,现阶段不宣称“部署环境完备”。
2.8 老板演示口径
当前可以说:
AgentOS 已经能在多轮对话中记住同一会话的障碍物目标、补全“绕过去”等省略指代,把自然语言转成受约束的高层任务计划,并在模拟器不可用时用
SIMCAR_REHEARSAL=1完成端侧离线演示:自然语言规划、白名单命令编译、单障碍绕行、实时麦克风/虚拟回放语音闭环都可展示。按老板要求的 Ascend 310B 端侧部署已经打通板端连通、模型盘点和 ONNX 导出,并已定位到 OM 转换的真实阻塞点。
当前不能说:
已经通过摄像头识别障碍物、具备任意抽象指令的 GPT 级理解、完成未知环境自主导航、或已在实体小车/目标端侧硬件上跑通运动;310B 上也还没有产出可交付的 OM、跑通板端 SenseVoice 推理。
三、产出
本周形成的可交付物按“端侧能力 / 基准与证据 / 310B 部署 / 文档归档”四类汇总:
端侧能力
├── DialogueContextStore # 有界会话上下文与安全指代补全
├── L1 确定性快速路径 # 基础动作不再依赖 LLM 漂移
├── 绕障前进收敛模板 # navigate_forward(distance_cm, side)
├── SIMCAR_REHEARSAL=1 # 模拟器不可用时的离线预演模式
└── 实时语音闭环 # WSLg 采集 + VAD + SenseVoice + 高优停车
基准与证据
├── 36 条中文规划基准 # L1-L4 + 8 条安全样例
├── raw / final 双口径统计 # 18/36 → 36/36;安全 2/8 → 8/8
├── demo_gate / model_gate # demo 通过,model 未通过
└── 权威回归 # 355 passed / 10 skipped
Ascend 310B 部署
├── 板端连通与盘点记录 # UART / SSH / NPU / CANN / 分区
├── SenseVoiceSmall ONNX # opset14 ≈ 895MiB,板端 SHA256 一致
├── voice_robot/asr/ascend_backend.py
├── requirements-ascend.txt
├── scripts/setup_ascend_board.sh
├── scripts/run_ascend.sh
└── README 310B 部署说明
文档归档
├── 周报/第3周-2026-07-20~2026-07-24.md
├── 工作日志/ # 本周详细实施记录
├── 总览/ # 总体设计与约束
└── SimCar/ # 代码、契约、演示与交接
关键量化结果速览:
| 项 | 结果 |
|---|---|
| 合成语音整链 | 5/5 |
| 规划基准 raw | 18/36 = 50.0% |
| 规划基准 final | 36/36 = 100% |
| 安全 raw / final | 2/8 → 8/8 |
| raw model p95 | 3.99s |
| final pipeline p95 | 2.04s |
| 回归测试 | 355 passed / 10 skipped |
| 310B OM | 尚未产出可交付 OM(阻塞在工具链算子包) |
四、下周计划
核心目标:把多轮绕障从“单障碍会话补全”推进到“可接感知快照的多障碍路线”,并继续打通 310B 端侧 SenseVoice 可运行基线。
- 感知契约对齐:与模拟器同事约定结构化感知快照契约(
scene_observations:source / confidence / observed_at / 坐标 / 半径),把已知场景几何绕障扩展到多障碍全局路线; - 模型对比评估:在同一 36 条基准上评估 3B / 7B 端侧模型,给出与 1.5B 的成功率 / 时延对比,决定是否引入模型级联;
- 轨迹终点精度契约:dry-run 推进预测位姿、在线执行比对实际位姿,让 Judge 拒绝“命令发完但车没走到”的假完成;
- Ascend 310B 部署推进:在板端自带 CANN 9.0.1 OPP 上完成
Ascend310B1/ FP16 / 固定时长的 OM 转换,补齐或改写 ACLLite 依赖,跑通单音频端到端基线,再评估 INT8 校准; - 动态重规划骨架:增加执行期动态感知刷新与局部重规划的骨架设计,为真实感知服务接入留边界。
五、相关归档
- 本周详细日志:
工作日志/; - 总体设计和约束:
总览/; - SimCar 代码、契约、演示和交接:
SimCar/; - 上周记录:
周报/第2周-2026-07-14~2026-07-18.md。