目录

答疑精编 · 你问过的九轮问题

这份文档是什么 你把讲解稿拿去问了另一个 AI,一共问了九轮。你提的每个问题都是真实的理解断点, 所以这份文档保留那个问答结构,把有用的部分提纯,把讲错的部分标出来

为什么必须标出错的部分 你已经读过那个版本了。如果我只是悄悄删掉错的地方,你脑子里留下的还是错的版本, 面试现场会说出口。 所以下面凡是它讲错的,我都写清楚: 它当时是怎么说的 → 这句为什么是错的 → 正确的是什么 → 依据是 TEST-LOG 哪一条。

术语扫盲.md 的分工 那份是按词查的(不懂某个词就去查),这份是按你问的顺序看的。 有些解释扫盲稿里写得更细,这里就不重复了,直接标了去看哪一节。


【先看这个】勘误表

下面九条,是那份对话里和实测对不上的地方。 先把这九条过一遍,再往下看问答。

一、四处数字讲错了

错误 1:把 PyTorch 省的显存说成是 TensorRT 省的

它当时说的

「显存:直接从 345 MB 砍到了 178 MB。」(放在 TensorRT 那一段的成果里)

为什么错345.3 MB 和 178.7 MB 这两个数,是 PyTorch 自己从 FP32 换到 FP16 测出来的,跟 TensorRT 没关系。

正确的说法

如果被问到显存,正确的答法

「显存我只有 PyTorch 那两个后端的可比数字,FP32 是 345 MB、FP16 是 179 MB。 TensorRT 和 ORT 用的是自己的内存分配器,不进 PyTorch 的统计接口,所以我没有它们的可比数字,这一格是空的。

依据TEST-LOG.md T-007,显存那一列只有 PyTorch 两行有数,其余标的是「—」。


错误 2:把 76.2% 带宽当成成绩,丢掉了真实形状只有 7.3%

它当时说的

「手写 CUDA Kernel 融合……独立测试达到 76.2% 峰值带宽。

为什么错这不是完整的一半。 76.2% 是在把数据放大 50 倍的合成形状上测的; 在模型真实的形状上只有 7.3%。

而 7.3% 那一半才是重点。

这一列的价值恰恰在于它暴露了一个问题

证据:数据量放大 50 倍,耗时只涨 4.8 倍。如果真是带宽受限,应该等比例涨。

这个 7.3% 直接预告了第 19 步的负结果。 只讲 76.2% 就把这条线索砍断了。

正确的说法

「这个 kernel 在放大 50 倍的合成数据上能跑到峰值带宽的 76.2%,说明它本身写对了但在模型真实的形状上只有 7.3%——张量太小,还没跑到带宽瓶颈就结束了。 后面这个数字才是关键,它预告了我第 19 步的失败。

依据TEST-LOG.md T-008。


错误 3:说 FP16 几乎零精度损失

它当时说的

「TensorRT FP16 …… 精度几乎无损」 「精度:在 FP16 下几乎零精度损失。」 表格里还写了「机械臂角度误差:几乎零误差

为什么错FP16 的物理误差(多少度)那一格,我根本没测。

我测过的是:

FP16 engine 的物理角度误差,没有对应的实测数字。

"几乎零损失"这个结论我没有数据支撑,不能说。

正确的说法

「FP16 的误差我只测了归一化空间的数值,是 6.4e-03。我没有把它换算成角度,所以我不能说它几乎无损。 我有角度数字的只有两个:模拟量化是 0.69 度,真 INT8 是 8.39 度。」

依据TEST-LOG.md T-007(FP16 只有归一化空间误差)、T-011 与 T-012(物理量只覆盖那两项)。


错误 4:把「模型结构不是我设计的」这句免责整句删掉了

它当时做的:讲解稿三十秒结论里有这么一句——

这个模型的结构是比赛官方 benchmark 仓库提供的,权重是我训出来的,这次的部署链路是我做的。

它把这句整个删掉了。全文 998 行,一次都没提官方仓库。

为什么这是四处里最危险的一处: 其他三处是数字讲错,这一处是把"哪些不是你做的"这个边界抹掉了。

如果你按它的版本讲,面试官会默认整个模型都是你的一旦被问到"这个结构你为什么这么设计",当场就穿; 而且这属于把别人的工作说成自己的,比不会更糟。

正确的说法(务必加回去)

「这个模型的结构是比赛官方发的 benchmark 仓库提供的,权重是我训出来的这次的部署链路是我做的。」

依据docs/术语扫盲.md 第 0 节整节都在讲这个,建议单独读一遍。


二、它丢掉了三条边界,要补回来

这三条都是限制条件。它一条没提,讲的时候要补上。

边界 1:INT8 的结论只建立在 32 帧校准集上

没提到的

该怎么说

「我的 INT8 结论建立在 32 帧校准集上,这个数量偏少,工业上通常几百到上千帧。 更多帧可能会让误差下降,但我没做校准集大小的消融,说不清能降多少。 QAT 我也没做——如果 INT8 是硬需求而后训练量化精度不够,那才是正确的下一步。」

依据TEST-LOG.md T-012「没覆盖什么」那一段。


边界 2:没有闭环任务成功率,所以只能给数字不能给结论

这条最重要,它整份对话里完全没提。

0.69 度、8.39 度这些数字,我能测出来,但我判断不了"能不能接受"。

为什么:真正的判据是机器人实际做任务的成功率, 而跑成功率需要仿真环境和评测服务端,这些我没有。

该怎么说

「这些角度误差我能给数字,但我给不了'能不能接受'的结论。 因为真正的判据是任务成功率,而跑闭环需要仿真环境和评测服务端,我没有。 我能做的是把取舍摆出来,让使用方按自己的精度需求选。

依据TEST-LOG.md T-011、T-012 的「没覆盖什么」。


边界 3:中途换过 ckpt,而且重算的统计文件没法验证

没提到的两件事

  1. 换过模型文件:前半程用的是一个任务的权重,后半程因为本地只有另一个任务的数据,换成了另一个。 结构完全相同,所以延迟、节点数、图优化这些结论不受影响; 但精度数字不能跨两个权重逐一对比。
  2. 重算的归一化统计文件,没法和训练时的原值比对——因为原文件已经丢了,没有东西可以对比。 所有把误差换算成"多少度"的数字,都依赖这份重算的表。

该怎么说

「有两件事我得说清楚。一是我中途换过一次模型权重,因为本地只有后一个任务的数据。 结构一样,所以速度和图优化的结论不受影响,但精度数字不能跨两个权重比。 二是那份归一化统计文件是我用原始数据重算的,我没法证明它和训练时用的完全一致, 因为原文件丢了、没有比对对象。所以我标的是'重算值,未与原值比对过'。 不过数量级的结论不受影响——27 度就算差两成,还是不能用。」

依据TEST-LOG.md T-011。


三、它编了两处因果,要删掉

编造 1:把 12.8 毫秒说成"机器人卡顿"

它当时说的

「如果模型算一步要 13 毫秒,机械臂反应就会卡顿」 「PyTorch GPU 耗时 12.8 毫秒(1 秒只能处理 78 帧,机器人动作卡顿)」

为什么不能说

  1. 这个项目没有做过任何闭环验证,机器人到底卡不卡顿,我没有观察过。
  2. 更关键的是:这个模型一次输出 50 步动作(action chunking), 推理不是每个控制周期都发生一次。用"每秒能推理多少次"直接推"动作流不流畅",前提就不成立。

该怎么说什么都别说。 只报延迟数字,不引申到机器人行为。

「PyTorch 上单次推理是 12.816 毫秒。」——说完就停。


编造 2:把 1.1 毫秒说成"工业级实时控制"

它当时说的

「TensorRT FP16 耗时 1.1 毫秒(……1 秒能处理 900 帧,达到工业级实时控制)」

为什么不能说:同上——没有闭环验证,说不了"达到了什么级别"。 而且"工业级实时控制"是个没有明确定义的说法,被问一句"你的判据是什么"就答不上来。

该怎么说

「TensorRT FP16 单次推理 1.104 毫秒,相对 PyTorch 快 11.65 倍。」——说完就停。

这两处删掉之后,你的数字反而更可信——因为它们只声称了你真的测到的东西。


四、它用了一个已经被推翻的理由

它在第 14 步说:选择优化 FFN,是因为 FFN 占比最大、最耗时

这个理由在第 16 步已经被我自己的 profile 实测推翻了。

实测结果:FFN 相关的矩阵乘 0.677 毫秒,attention 相关的 1.369 毫秒—— FFN 只占 attention 的 0.49 倍,方向和参数量的预测完全相反。

所以正确的讲法是分两层

  1. 当时的理由(按时间顺序讲,这是真实发生的): 我按参数量分析,FFN 的参数是 attention 的 3.12 倍、重复 11 次,所以我判断它最耗时
  2. 后来的修正(第 16 步): profile 实测推翻了这个判断。但这个 kernel 的选择依然站得住,只是理由要换—— FFN 的单次矩阵规模最大(512×3200),是这个模型里唯一有机会吃满算力的部分, 而且反量化+偏置+激活这个组合本来就长在 FFN 后面,位置是对的。

该怎么说

「我当时是按参数量选的 FFN——它参数是 attention 的 3.12 倍、重复 11 次。 但后来我做 profile,实测把这个判断推翻了,FFN 实际只占 attention 的 0.49 倍。 选择本身我认为还是对的,但理由要换:FFN 的单次矩阵规模最大,是唯一有机会吃满算力的部分。」

依据DECISIONS.md D-023、TEST-LOG.md T-010。


五、语气:有几个说法要去掉

那份对话里用了不少这类词:辉煌战果、震慑住面试官、暴涨、完胜、打脸、最牛的实验、硬核答卷

建议全部不用。 原因很实际:

这套材料最强的地方是它的克制——每个数字都标了怎么测的、每个推断都标了"这是推断没实测"、 边界写在最前面而不是藏在最后。

如果你讲的时候语气突然变成"这是我最牛的部分",那个语气跟材料本身是冲突的,反而会让人怀疑。

平铺直叙地说完,让面试官自己判断。

别说 改成
先用数字震慑住面试官 先给结论,再讲过程
误差从 0.69 暴涨到 8.39 误差从 0.69 度变成8.39 度
FP16 完胜 FP16 是更好的点(并说明是在什么维度上
被自己的数据打脸 被实测推翻了 / 我这里想错了
最牛的实验 我事先预测它是负结果,实测确认了


问答正文(九轮)


第 1 轮

你问:「接下来,需要你帮我逐个解释,我说实话我看不懂。」

这一轮它做了个整体概述。概述里就带着上面说的错误 1 和错误 3(显存归给 TensorRT、FP16 无损), 以及"震慑住面试官"那句语气问题。

这一轮真正有用的,是它把项目拆成了"主线 + 支线"这个框架,这个框架是对的:

主线(第 1~13 步):把模型从 PyTorch 搬到 TensorRT,跑得更快
支线(第 14~20 步):四个验证性实验,其中三个是负面结果

更详细的地图在 术语扫盲.md 第 5 节开头,那里有一张表列了 14~20 步各自在回答什么问题。


第 2 轮

你问:「CVAE Encoder?特征图?训练仓?哪来的?」

这三个词扫盲稿里都写得更细,直接去看:

去哪看
CVAE Encoder 术语扫盲.md 第 2 节 ·【第 1 步】CVAE
特征图 术语扫盲.md 第 2 节 ·【第 1 步】特征图
训练仓哪来的 术语扫盲.md 第 0 节(整节)

这里只强调一件事「训练仓」这个词本身有误导性。

它指的是比赛官方发的 benchmark 仓库,不是你的项目。 那份对话从头到尾没提过这一点(就是勘误表里的错误 4)。

讲的时候建议直接说全"比赛官方给的那个 benchmark 仓库", 别只说"训练仓"——听起来像是你自己的东西。


第 3 轮

你问:「CVAE Encoder 是用来训练学习的,而不是用来推理的,对吗?」

你这个理解是对的。 这一轮没有需要纠正的地方。

补充两个可以直接用的数字:

怎么证明真的砍掉了(这个证据面试时很有用):

「PyTorch 那边模型是 83.9M 参数,导出的 ONNX 图里只有 66.5M, 差的 17.4M 正好是推理时不跑的那部分。如果它被带进去了,文件体积会直接涨 20%,一眼能看出来。


第 4 轮

你问:「ONNX 是不是类似于 gguf?」

这一轮是整份对话里最有价值的一轮,因为这个类比是你自己提出来的,而且它是准的。

它说明你有本地跑大模型的心智模型——这是个很好的锚点,讲的时候可以直接用。

核心对应关系

ONNX 之于 PyTorch,就像 GGUF 之于 HuggingFace 的原始模型。

两者都是为了脱离原来的训练框架、拿去别处跑。 你从 HuggingFace 下的模型要装一整套 Python 环境才能跑,转成 GGUF 之后 llama.cpp 直接读; PyTorch 训练的模型要装 PyTorch 才能跑,导出 ONNX 之后 TensorRT、地平线工具链都能读。

但有一个关键区别(这个区别正好回答了你下一轮问的"ONNX 不是最终格式吗"):

GGUF ONNX
拿到之后 直接就能跑 还要再编译一道
定位 终点 中转站

完整版在 术语扫盲.md 第 2 节 ·【第 4 步】ONNX,那里有更详细的对照表。


第 5 轮

你问:「ONNX 不是已经是最终格式了吗?engine 是什么?TensorRT 是什么忘了。 第 12 步是不是可以理解为缓存或者查表?四种办法是什么没明白?ORT 是什么?第 13 步是啥啊?」

这一轮你一口气问了六个,扫盲稿里我专门开了两节回答,直接去看:

你问的 去哪看
ONNX 不是最终格式吗 / engine / TensorRT 术语扫盲.md 第 3 节开头
第 12 步在干嘛(你猜是缓存或查表) 术语扫盲.md 第 3 节
四种办法是什么 术语扫盲.md 第 3 节
ORT 是什么 / 第 13 步是啥 术语扫盲.md 第 4 节

这里只留三条最要紧的:

1. 你猜第 12 步是"缓存或查表"——方向是对的。 准确说法是"提前算好存起来"。那个东西(位置编码)只跟图片切成几行几列有关, 跟图上画的什么完全无关,而我的图片尺寸是固定的,所以它永远是同一套结果, 却被留在流程里每次重算一遍。我把它在加载时算一次存下来,运行时那段计算就不存在了。

2. "四种办法"是在排查一个 bug 时试的四种参数组合,四种全部失败在同一个位置。 这个结果本身就是信息——既然怎么调参数都失败在同一处,说明问题根本不在参数上, 方向就排除了。然后我才去查"那个位置的数据从哪来的",找到了真正的原因。

3. 第 13 步里有个坑值得单独记: 我让 ORT 用显卡跑,它给了我 38 毫秒这个数字。 但我脚本里多打印了一行"你实际用的是显卡还是 CPU",它回答 CPU它显卡加载失败之后不报错,默默切回 CPU,照样给你结果。 修好之后是 3.677 毫秒,差了十倍


第 6 轮

你问:「FFN 是什么?CUDA 算子是什么?干嘛的?另外那个量化,我看你的意思是,可以只量化一部分? profile 是什么?」 你还说:「这一轮的基本上都没看懂。」

你说没看懂,所以扫盲稿第 5 节把 14~20 步整个重讲了一遍,那里最详细。这里给要点:

你问的 一句话 详见
FFN Transformer 每层里的"加工车间",把数据放大 6.25 倍、过滤、再压回来,重复 11 次 扫盲稿第 2 节
CUDA 算子 写给显卡的一段小程序(下一轮你自己给了个很好的类比 扫盲稿第 2 节
能只量化一部分吗 能,而且我实测发现这么做更好 扫盲稿第 5 节 · 第 15 步
profile 测量工具,告诉你时间具体花在哪一步 扫盲稿第 5 节 · 第 16 步

关于"只量化一部分",这里给完整答案,因为这是个好问题:

我做了逐层实验,看哪部分压缩之后影响最大。发现:

方案 体积 误差(相对全压)
全部压缩 130 MB 1.00
只压 FFN 179 MB 0.19

多花 49 MB,误差降到五分之一。 因为 FFN 体积最大、但每单位参数的影响最小。

这一轮我还犯过一个错,值得一起讲: 我看到某个很小的部分"每单位影响最大",就推论排除它误差会明显下降去验证,结果只改善了 8%。 错在哪:它虽然每单位影响大,但它总共才占万分之二,乘起来总影响很小。 "每单位影响"和"总影响"是两个指标,我用错了。


第 7 轮

你问:「这个算子,有点像 x86 和 AMD?」

这一轮也是你自己提出来的类比,而且比一般人想到的更准。

准确地说,像的是指令集:

位置关系对照

CPU 世界 GPU 世界
硬件架构 x86 / ARM CUDA(NVIDIA)/ ROCm(AMD)
你写的东西 C++ / 汇编 / AVX 指令 CUDA 算子(.cu 文件)
优化手段 用复合指令代替多条普通指令 算子融合:一个 kernel 代替多个

完整版在 术语扫盲.md 第 2 节 ·【第 8 步】kernel。

一个补充:这一轮它讲的 kernel 选择理由("FFN 占比最大所以最耗时") 是已经被推翻的旧版本,正确的讲法见勘误表第四条。


第 8 轮

你说:「17 和后边基本上全没看懂。」

这一轮的内容整个被我重写进了 术语扫盲.md 第 5 节(第 17~20 步那几段), 那里是全文最厚的一节。这里只给三个最要紧的结论

第 17 步做了什么:把之前用随机假图片做的测试,换成真实的机器人画面重测。 结果:误差比之前大了 4 倍——随机数据系统性地把误差测低了。 同时,因为重算出了那份丢失的换算表,终于能把误差翻译成"多少度": 压到 8 位是 0.69 度,压到 4 位是 27.45 度

第 18 步做了什么:做一个真正压缩过的成品(之前都是模拟)。 结果:速度没赚到(1.123 毫秒 vs FP16 的 1.104 毫秒),误差却是模拟预测的 12 倍 (8.39 度 vs 0.69 度),只换来体积减半。

第 19 步做了什么:把第 14 步手写的那段代码真接进模型。 结果:端到端慢了 37%。我在写实验代码时就在文件开头预测了它会失败预测的理由和实测的原因完全一致。

关于"8.39 度"这里要纠正一处措辞: 那份对话把它写成了"手指关节彻底歪了"这种确定结论。 准确说法是:8.39 度是我测到的数字,它落在灵巧手的手指关节上, 而手指是精细抓取里最吃精度的部位。但"能不能用"这个结论我给不了—— 判据是任务成功率,而我没有闭环评测环境。


第 9 轮

你说:「说白了,如果单纯从结果来看是比较失败的。」

这句话我在 术语扫盲.md 第 6 节整节回应了,建议直接读那一节。这里给要点:

你会这么想是正常的——第 14 步之后连着三个负面结果, 而那几步恰好是你说没看懂的部分。看不懂的部分连着说"失败",自然觉得整个项目不行。

但主线是通的

PyTorch 原始    12.816 毫秒
TensorRT FP16    1.104 毫秒      快了 11.65 倍

这个数字是实测的、有完整测法记录、可复现。

那三个负面结果的性质,是"验证了一个假设,结果假设不成立",不是"做砸了"

但语气要压住。 你不需要把这些说成"最牛的部分",那种语气反而会让人怀疑。 平铺直叙说完,不加评价,让面试官自己判断。

一个更准确的自我评价(可以照念)

「主线是通的——从 PyTorch 到 TensorRT,11.65 倍,数字都是实测的。 支线上我做了几个验证性实验,其中两个结论是负面的:INT8 对这个模型不划算, 我手写的算子接进去反而变慢。这两个负面结论我都留着,因为它们本身就是结论。 另外有两个判断被我自己的 profile 数据推翻了,我也照实记在文档里了。」

最后:这个项目真正的边界不是那三个负面结果,是这两条—— 你没有真实的端侧板子(JD 明确要求的一条经验,你是空的)、 你没有闭环成功率数据(所以精度问题只能给数字给不了结论)。 这两条才是要主动说的。


附:这份对话里可以直接拿去用的东西

去掉错误和夸张之后,那份对话真正留下来的有价值的东西是这三样:

  1. ONNX ↔︎ GGUF 的类比(第 4 轮,你自己提的) —— 说明你有本地跑大模型的经验,是个很自然的切入点
  2. CUDA 算子 ↔︎ x86 指令集的类比(第 7 轮,也是你自己提的) —— 融合算子 ≈ 一条复合指令代替多条普通指令
  3. "主线 + 支线"这个框架(第 1 轮) —— 前 13 步是主线,14~20 步是四个验证性支线

其余的解释,扫盲稿里都写得更准也更细。


附:所有数字的出处

凡是要报数字的场合,一律以下面这些为准,不要用那份对话里的:

数字 出处
12.816 ms → 1.104 ms,11.65 倍 TEST-LOG.md T-007
显存 345.3 / 178.7 MB(仅 PyTorch T-007
带宽 76.2%(合成)/ 7.3%(真实形状) T-008
FP16 归一化误差 6.444e-03(无物理量 T-007、T-012
量化物理误差 0.69 度 / 27.45 度 T-011
真 INT8:1.123 ms / 65 MB / 8.39 度 T-012
kernel 接入端到端 0.729 倍、+191 个任务 T-013
FFN vs attention 0.49 倍(推翻原判断 T-010
模型结构来自官方 benchmark 仓库 术语扫盲.md 第 0 节