<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Helmsman：端侧（SOC）AI 人像抠图 — 从模型到部署的全栈工程 on Potter的个人笔记</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/</link><description>Recent content in Helmsman：端侧（SOC）AI 人像抠图 — 从模型到部署的全栈工程 on Potter的个人笔记</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Fri, 28 Aug 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://potterwhite.github.io/portfolio/edge-ai/helmsman/index.xml" rel="self" type="application/rss+xml"/><item><title>Chapter 1: 黄金参考系统 — 在 x86 上搭建像素级对齐的 C++ 推理管线</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage1-golden-reference/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage1-golden-reference/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-1-building-a-golden-reference-system"&gt;&lt;strong&gt;Chapter 1: Building a Golden Reference System&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — Golden Reference System&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Foundation F1&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-01 ~ 2026-02&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：如何确保 C++ 推理管线与 Python 参考实现 100% 像素级对齐？为什么需要这一步？（后续所有板端测试都以这个 baseline 为参照）--&gt;
&lt;h3 id="2-goal-review"&gt;&lt;strong&gt;2. Goal Review&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- 目标：在 x86 PC 上搭建完整的 C++ 推理管线
- 验收标准：C++ 输出与 Python baseline 的 tensor 数据 md5 完全一致
- 技术栈：OpenCV + ONNX Runtime + CMake
--&gt;
&lt;h3 id="3-implementation"&gt;&lt;strong&gt;3. Implementation&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：具体步骤，建议用流程图 + 文字说明：

```mermaid
graph LR
 A[Python demo.py] --&gt;|导出 reference_tensor.txt| B[对比]
&lt;pre&gt;&lt;code&gt;C[C++ preprocess] --&amp;gt;|导出 cpp_tensor.txt| B
B --&amp;gt;|diff 无差异| D[✅ 对齐成功]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
步骤：
1. 预处理对齐：OpenCV resize + normalize [0,255]→[-1,1] + HWC→CHW
2. 推理引擎封装：InferenceEngineONNX 类（Load + Infer）
3. 后处理：pha tensor → alpha matte → alpha blend
4. 验证：md5 逐字节对比
--&amp;gt;

### **4. Key Challenge: 归一化精度 Bug**

&amp;lt;!-- 填入：
- 现象：bitwise 对比失败，Python 和 C++ 的 tensor 数据有微小差异
- 根因：float 精度差异（浮点运算顺序不同导致的舍入误差）
- 解决：统一 normalize 实现，确保逐元素操作顺序一致
- 参考 PKB：bug-F1-normalization-bitwise.md
--&amp;gt;

### **5. Outcome**

&amp;lt;!-- 填入：
- C++ 输出与 Python baseline md5 一致 ✅
- Golden Reference 作为后续所有板端测试的 baseline
- 封装了可复用的模块：TensorData、InferenceEngineONNX、Preprocessor
--&amp;gt;

### **6. Reusable Assets**

&amp;lt;!-- 填入：表格，列出这一阶段产出的可复用代码/工具：

| 资产 | 路径 | 说明 |
|------|------|------|
| TensorData | include/.../tensor-data.h | 统一的 tensor 数据结构 |
| InferenceEngineONNX | src/.../inference/onnx/ | ONNX Runtime 封装 |
| Preprocessor | src/.../frontend/preprocessor.cpp | 预处理模块 |

--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Chapter 2: 网络手术 — IBNorm→BatchNorm 与 ONNX 导出</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage2-model-surgery/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage2-model-surgery/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-2-network-surgery--ibnorm-to-batchnorm"&gt;&lt;strong&gt;Chapter 2: Network Surgery — IBNorm to BatchNorm&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — Round 1 Model Surgery&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;MR1 Phase-1&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-03-12 ~ 2026-03-19&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：为什么 InstanceNorm 导致 NPU 量化崩溃？如何在不重训整个模型的情况下替换它？--&gt;
&lt;h3 id="2-problem-discovery"&gt;&lt;strong&gt;2. Problem Discovery&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- 现象：RKNN FP16 推理时发现 InstanceNorm 导致 NPU 反复 fallback 到 CPU
- 量化后 matte 出现大面积白斑噪声
- 参考 PKB：log-DR1-RKNN-pre-T2.3-ibNorm.md
--&gt;
&lt;h3 id="3-root-cause-analysis"&gt;&lt;strong&gt;3. Root Cause Analysis&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：InstanceNorm 的数学分析（参考 PKB summarize-MR2-G0 Q1）：

IN 的计算公式：
```
μ[n,c] = mean over H,W of x[n,c,h,w]
σ[n,c] = std over H,W of x[n,c,h,w]
y = (x - μ) / (σ + ε)
```

关键矛盾：
- INT8 量化需要一个固定的 scale：`q = round(x / scale)`
- 但 IN 的统计量 μ,σ 随输入动态变化
- 单个固定 scale 无法覆盖 IN 内部的动态范围 → 精度崩溃

对比 BatchNorm：
- BN 的 running_mean、running_var 训练后是固定常数
- 量化工具可以精确确定 scale → INT8 无障碍

附一个对比表：

| | InstanceNorm | BatchNorm |
|---|---|---|
| 统计量 | 每张图、每通道动态计算 | 训练后固定常数 |
| INT8 可行性 | ❌ 动态范围无法覆盖 | ✅ scale 精确 |
| NPU 兼容性 | ❌ 反复 fallback CPU | ✅ 原生支持 |

--&gt;
&lt;h3 id="4-solution-bn-surgery"&gt;&lt;strong&gt;4. Solution: BN Surgery&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- 方法：逐层替换 IBNorm → BatchNorm（网络外科手术）
- 训练：P3M-10k 数据集 15 轮微调
- 结果：Val L1 = 0.0086
- 参考 PKB：log-MR1-B1.1-architecture-hack.md、log-MR1-B1.2-finetuning.md
--&gt;
&lt;h3 id="5-onnx-export--踩坑记录"&gt;&lt;strong&gt;5. ONNX Export — 踩坑记录&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：4 次失败的过程（参考 PKB log-MR1-B1.4-onnx-export.md）：
1. Python 环境 bug（依赖冲突）
2. opset 版本选择（opset 11 vs 12）
3. 动态 shape 处理
4. 最终成功导出 25MB ONNX
--&gt;
&lt;h3 id="6-validation"&gt;&lt;strong&gt;6. Validation&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- C++ 推理语义正确（无白斑）
- 发丝模糊可由 Guided Filter 恢复
- 决策：跳过蒸馏，提前做 GF 后处理
- 参考 PKB：log-MR1-B1.4-pureBN-vs-IBNorm.md
--&gt;
&lt;h3 id="7-key-insight"&gt;&lt;strong&gt;7. Key Insight&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：这一章的核心收获。比如："不绕过问题，而是从根本上解决" 的工程态度。BN 手术虽然看起来是个 workaround，但实际上是从数学层面理解了问题的本质后做出的正确决策。--&gt;</description></item><item><title>Chapter 3: RKNN 移植与 ONNX Graph Surgery</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage3-rknn-porting/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage3-rknn-porting/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-3-rknn-porting-and-onnx-graph-surgery"&gt;&lt;strong&gt;Chapter 3: RKNN Porting and ONNX Graph Surgery&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — RKNN Porting + Graph Surgery&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;DR1 RKNN + MR2 Phase-1~2&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-04-02 ~ 2026-04-11&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：如何把 ONNX 模型转换为 RKNN 并在 NPU 上跑通？遇到不兼容的算子怎么办？--&gt;
&lt;h3 id="2-arcfoundry-yaml-driven-rknn-conversion"&gt;&lt;strong&gt;2. ArcFoundry: YAML-Driven RKNN Conversion&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- ArcFoundry 是什么：一个 YAML 驱动的 ONNX→RKNN 转换框架
- 设计理念：配置驱动，一个 YAML 文件定义一个模型的完整转换参数
- 支持的能力：多分辨率配置、动态 shape 固定、常量折叠、graph surgery
- 参考 PKB：log-MR2-P1-block1.4-arcfoundry-config.md
--&gt;
&lt;h3 id="3-modnet-rknn-fp16-benchmark"&gt;&lt;strong&gt;3. MODNet RKNN FP16 Benchmark&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：4 分辨率 benchmark 表格（参考 PKB plan-DR1-RKNN-roadmap）：

| 分辨率 | FP16 耗时 | BN 提速 | 备注 |
|--------|----------|---------|------|
| 256×256 | ~XXms | +XX% | |
| 512×512 | ~130ms | +30-45% | |
| ... | | | |

--&gt;
&lt;h3 id="4-graph-surgery--移除-deepguidedfilterrefiner"&gt;&lt;strong&gt;4. Graph Surgery — 移除 DeepGuidedFilterRefiner&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：这是最有技术深度的部分。参考 PKB summarize-MR2-ending.md §3.1：

**背景**：RVM 的 ONNX 模型包含一个 DeepGuidedFilterRefiner，导出时 strict=False 静默丢弃了 15 个权重，实际用 FastGuidedFilter 替代。

**过程**：
1. 逆向 ONNX 图结构，精确定位 decoder/refiner 边界（Conv_294 → Split_295）
2. 移除 58 个节点（index 295-352），含两个 Resize 算子（各 ~10.8ms）
3. 用 C++ Guided Filter 替代模型内置 refiner，NPU 推理 -34ms

**泛化**：这个操作被抽象为 ArcFoundry 配置驱动的 GraphSurgeon 策略类，任何模型可通过 YAML 配置做 graph surgery。

建议用 Mermaid 画一个 before/after 的图结构对比。
--&gt;
&lt;h3 id="5-rvm-round-2-gate-0--rknn-fp16"&gt;&lt;strong&gt;5. RVM Round 2: Gate-0 → RKNN FP16&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- Gate-0 可行性评估：7 条观测点全 GO（参考 PKB log-MR2-G0-feasibility.md）
- ONNX 导出：5 输入（src + r1i~r4i）+ 6 输出（fgr + pha + r1o~r4o）
- downsample_ratio 折叠为常量：6 输入 → 5 输入
- RKNN FP16 板测：288×512 45.7ms, 256×256 20.5ms (48fps)
- 参考 PKB：log-MR2-P2-rknn-fp16.md
--&gt;
&lt;h3 id="6-guided-filter-experiments"&gt;&lt;strong&gt;6. Guided Filter Experiments&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：11 轮实验收敛的过程（参考 PKB plan-DR1-GF-roadmap.md）：
- 最终参数：r=2, ε=1e-4, threshold=0.2, erode=1
- 关键发现：GF 在 288×512 输入下无效（模型输出仅 72×128，信息不足）
- GF 在 1080p 输入下 95+ 分，完全替代内置 DeepGuidedFilter
--&gt;
&lt;h3 id="7-reusable-assets"&gt;&lt;strong&gt;7. Reusable Assets&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：表格

| 资产 | 说明 |
|------|------|
| ArcFoundry 框架 | YAML 驱动的 RKNN 转换，支持 graph surgery |
| GraphSurgeon 策略类 | 配置驱动的 ONNX 图手术 |
| Guided Filter 后处理 | boxFilter 纯 OpenCV 实现，可配参数 |

--&gt;</description></item><item><title>Chapter 4: C++ 推理流水线工程</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage4-pipeline-engineering/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage4-pipeline-engineering/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-4-engineering-a-production-grade-c-inference-pipeline"&gt;&lt;strong&gt;Chapter 4: Engineering a Production-Grade C++ Inference Pipeline&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — C++ Inference Pipeline&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;MR2 Phase-3 + Phase-5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-04-11 ~ 2026-04-18&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：如何设计一个可换引擎、可换预处理策略的端到端推理框架？--&gt;
&lt;h3 id="2-architecture-nvi-pattern"&gt;&lt;strong&gt;2. Architecture: NVI Pattern&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：三层解耦架构（参考 PKB _DASHBOARD.md 附录 B）：

```mermaid
graph TD
 A[Frontend] --&gt;|TensorData| B[InferenceEngine]
&lt;pre&gt;&lt;code&gt;B --&amp;gt;|vector&amp;lt;TensorData&amp;gt;| C[Backend]

subgraph Frontend
 A1[Input Source] --&amp;gt; A2[Decoder]
 A2 --&amp;gt; A3[Color Convert]
 A3 --&amp;gt; A4[Preprocess]
end

subgraph InferenceEngine
 B1[Inject States] --&amp;gt; B2[Quantize]
 B2 --&amp;gt; B3[NPU Execute]
 B3 --&amp;gt; B4[Dequantize]
end

subgraph Backend
 C1[Postprocess] --&amp;gt; C2[Composite]
end
&lt;/code&gt;&lt;/pre&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
设计原则：
- Preprocessor 只负责空间变换（resize, letterbox）
- Engine 负责精度变换（normalize, quantize, dequantize）
- Backend 负责数据提取 + 合成输出
- 三者正交，互不依赖
--&amp;gt;

### **3. Frontend: 4 Sub-Stages**

&amp;lt;!-- 填入：4 个子阶段的说明（参考 PKB _DASHBOARD.md 附录 B §2）：
1. Stage 01 Input Source：FFmpegInputSource，读取视频 packet
2. Stage 02 Decoder：MppFrameDecoder，硬件解码 H.264/H.265
3. Stage 03 Color Convert：RgaNv12ToBgr，RGA 硬件 NV12→BGR
4. Stage 04 Preprocess：resize + letterbox → TensorData(float32 [0,255])
--&amp;gt;

### **4. InferenceEngine: NVI + Factory Pattern**

&amp;lt;!-- 填入：
- NVI（Non-Virtual Interface）模式：Infer() 公开入口 → 注入状态 → DoInfer() 纯虚钩子 → 捕获状态
- 工厂模式：make_engine() 根据 INFERENCE_BACKEND 配置创建不同引擎
- 三路引擎：onnx | rknn-zerocopy | rknn-non-zerocopy

关键设计决策：为什么 Normalize + Quantize 放在 Engine 里？

| 引擎 | 输入量化方式 | 输出反量化方式 |
|------|------------|--------------|
| RKNN Zero-Copy | 手动：(pixel-127.5)/127.5/scale+zp 写入 DMA | 手动：(val-zp)*scale 从 DMA 读出 |
| RKNN Non-Zero-Copy | rknn_inputs_set(pass_through=0) | rknn_outputs_get(want_float=1) |
| ONNX Runtime | 模型内嵌 QDQ 节点 | 模型内嵌 QDQ 节点 |

如果把 normalize 放到 Preprocessor 里，换引擎就要改 Preprocessor → 违反&amp;#34;换引擎只需重新编译&amp;#34;的设计目标。
--&amp;gt;

### **5. Multi-Model Support: MODNet + RVM**

&amp;lt;!-- 填入：
- MODNet：1-in/1-out，无状态
- RVM：5-in/6-out，有递归状态（r1i~r4i 注入/捕获）
- 设计：在旁边加新路，不改旧路（RecurrentStateManager）
- 参考 PKB summarize-MR2-G0 Q4
--&amp;gt;

### **6. Pipeline Modes: Sync → Double Buffer → Worker Thread**

&amp;lt;!-- 填入：三种模式的演进：
1. 同步模式：read → preprocess → infer → backend（串行）
2. 双 buffer 流水线：std::async 预取第 N+1 帧 decode+preprocess 与第 N 帧推理并行
3. 持久 Worker Thread：SingleSlotChannel&amp;lt;T&amp;gt; + 持久 worker thread 替换 std::async-per-frame，零线程创建开销

参考 PKB log-MR2-P5-video-pipeline.md Block 5.2 + 5.4
--&amp;gt;

### **7. Reusable Assets**

&amp;lt;!-- 填入：表格

| 资产 | 说明 |
|------|------|
| NVI InferenceEngine 基类 | 可扩展到任意模型 |
| 工厂模式 + 三路引擎 | 换引擎只需重新编译 |
| RecurrentStateManager | RVM 递归状态管理 |
| SingleSlotChannel&amp;lt;T&amp;gt; | 生产者-消费者通道，零锁开销 |
| ScopedTimer + StageAccumulator | 层级计时系统 |

--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Chapter 5: 打破速度极限 — DMA Zero-Copy、MPP 硬解与 NEON SIMD</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage5-speed-optimization/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage5-speed-optimization/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-5-breaking-the-speed-limit"&gt;&lt;strong&gt;Chapter 5: Breaking the Speed Limit&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — Speed Optimization&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;MR2 Phase-5&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-04-15 ~ 2026-06-08&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：从 6.9 FPS 到 20.91 FPS，瓶颈在哪里？每次优化的收益是多少？--&gt;
&lt;h3 id="2-baseline-profiling"&gt;&lt;strong&gt;2. Baseline Profiling&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：层级计时系统（ScopedTimer + StageAccumulator）的定位结果：

| 阶段 | avg (ms) | 占 mainloop |
|------|----------|-------------|
| frontend | 10.71 | 10.5% |
| execute_npu | 52.14 | 53.6% |
| backend | 30.94 | 30.4% |
| **mainloop** | **97.1** | **100%** |

结论：execute_npu 是绝对瓶颈（53.6%），但 backend 也有 30.4% 的优化空间。
--&gt;
&lt;h3 id="3-fps-演进历程"&gt;&lt;strong&gt;3. FPS 演进历程&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：表格（参考 PKB summarize-MR2-ending.md §5.1）：

| 里程碑 | FPS | 关键变化 |
|--------|-----|---------|
| s1 基线 | **6.9** | 全分辨率 float32 CPU |
| s4b | **10.6** | 模型分辨率 uint8 composite |
| s5.3 | **12.7** | RGA 硬件 resize（-63%/-64%）|
| s6 | **20.91** | DMA zero-copy 输出（-80% composite）|

建议用 Mermaid 画一个折线图或柱状图。
--&gt;
&lt;h3 id="4-dma-zero-copy--单次最大-fps-提升"&gt;&lt;strong&gt;4. DMA Zero-Copy — 单次最大 FPS 提升&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB summarize-MR2-ending.md §3.2）

**问题**：VideoWriter 输出到文件，每帧 39ms I/O 开销。

**方案**：
1. 构建 DmaKit 库（RAII 封装 /dev/dma_heap/system ioctl）
2. RKNN Zero-Copy Engine：5-input/6-output 多 tensor，DMA fd 输出
3. compositeToDma() 替代 VideoWriter，直接写入 DMA buffer

**结果**：FPS 12.7 → 20.91（+64.6%），composite: 49ms → 9.7ms（-80%）

**为什么 DMA Zero-Copy 有效？**
- 传统路径：NPU output → CPU memcpy → 文件写入（39ms）
- Zero-Copy 路径：NPU output 直接在 DMA buffer 中，零拷贝（9.7ms）
--&gt;
&lt;h3 id="5-mpp-硬解调试--五层-bug-剥洋葱"&gt;&lt;strong&gt;5. MPP 硬解调试 — 五层 Bug 剥洋葱&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB summarize-MR2-ending.md §3.4）

集成 Rockchip MPP 硬件 H.264 解码，连续踩中五个非显而易见的 Bug：

1. **MPP_ERR_BUFFER_FULL（-1012）**：buffer 满时当前 packet 永久丢失
2. **解码器无 Flush 方法**：241/363 帧提前终止
3. **AVCC vs Annex B 格式不匹配**：MP4 容器 vs MPP 期望
4. **3 帧绿色循环**：packet 丢失导致 MPP 内部 3 帧环形缓冲区循环旧帧
5. **RGA !src.data 检查**：在 ToRgaBuffer() 之前，拒绝纯 DMA fd 描述符

每一层 bug 的发现都是上一层修复后才能看到的 —— 这就是"剥洋葱"。
--&gt;
&lt;h3 id="6-neon-simd--精确到-001ms-的-profiling"&gt;&lt;strong&gt;6. NEON SIMD — 精确到 0.01ms 的 Profiling&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB summarize-MR2-ending.md §3.5）

- 先测量：write_input_buffers 仅 1.3ms（2.4% of infer），src 占 0.814ms，cache flush 仅 0.07ms
- 再优化：vcvt_f16_f32 / vcvt_f32_f16 intrinsics，write 1.3ms → 0.45ms（2.93× 加速）
- **结论：NEON 完美工作，但 write 不是瓶颈（execute_npu 52ms 占 93.7%）**
- 价值：精确 profiling 杀死了多个无效优化方向，NEON 库本身可复用
--&gt;
&lt;h3 id="7-librknnrtso-白盒分析"&gt;&lt;strong&gt;7. librknnrt.so 白盒分析&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB summarize-MR2-ending.md §3.3）

通过开源内核驱动（rknpu_job.c）+ NVDLA 架构文档 + SDK 文档，逆向闭源 runtime 行为。

找出 RKNN 比理论慢 4000× 的五个根因：
1. 中断驱动逐算子调度（每个算子 50-500μs CPU 开销）
2. RK3588 无 NPU 专用 SRAM（RK3576 有 1MB NBUF）
3. 算子融合仅 2-3 层 vs TensorRT 10+
4. GRU 不支持多核并行
5. I/O 用标量循环无 NEON（后被我们修复）

这些发现定量地解释了 RKNN 的性能天花板。
--&gt;
&lt;h3 id="8-reusable-assets"&gt;&lt;strong&gt;8. Reusable Assets&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：表格

| 资产 | 说明 |
|------|------|
| DmaKit 库 | RAII DMA buffer 分配 |
| NEON SIMD 库 | FP32↔FP16 转换，2.9× 加速，header-only |
| MppDecoder | H.264 硬件解码，dmabuf fd 输出 |
| RGA resize 集成 | Meyer's Singleton，4 硬件核心，线程安全 |
| ScopedTimer + StageAccumulator | 层级计时系统 |

--&gt;</description></item><item><title>Chapter 6: INT8 量化探索 — 发现 ConvGRU 的架构性死局</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage6-quantization-exploration/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage6-quantization-exploration/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-6-int8-quantization-exploration"&gt;&lt;strong&gt;Chapter 6: INT8 Quantization Exploration&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — INT8 Quantization Exploration&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Phase&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;DR1 INT8 + MR2 Phase-4&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-04-06 ~ 2026-06-05&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-core-question"&gt;&lt;strong&gt;1. Core Question&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：INT8 量化为什么对 RNN 模型是死路？这个发现的价值是什么？--&gt;
&lt;h3 id="2-modnet-int8--纯-cnn-路线"&gt;&lt;strong&gt;2. MODNet INT8 — 纯 CNN 路线&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
- 校准集准备：300 张 P3M train（参考 PKB ref-DR1-INT8-calibration-methodology.md）
- INT8 转换成功：5.5MB（FP16 9.0MB → 39% 压缩）
- 模拟器精度：pha cosine 0.999，fgr cosine 0.998 ✅
- 状态：Q.1 校准集 ✅ → Q.2~Q.7 待续（因转向 RVM 而暂停）
- 参考 PKB：plan-DR1-INT8-roadmap.md
--&gt;
&lt;h3 id="3-rvm-int8--纯-int8-崩溃"&gt;&lt;strong&gt;3. RVM INT8 — 纯 INT8 崩溃&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB log-MR2-P4-int8-quantization.md）

**实验结果**：
| 实验 | 方案 | 结果 |
|------|------|------|
| §24 | 纯 INT8 | pha cosine = 0.000000（全绿）|
| Exp1 | 纯 INT8 + auto-patch | score=0.000 + SDK bug |
| Exp2 | 纯 INT8 + 手动 cfg | SDK bug |

**根因分析**：
ConvGRU 的 r-state 逐帧累积量化误差，指数发散。

```mermaid
graph LR
 A[Frame 1] --&gt;|r-state| B[Frame 2]
&lt;pre&gt;&lt;code&gt;B --&amp;gt;|r-state + 量化误差| C[Frame 3]
C --&amp;gt;|r-state + 更大误差| D[Frame N]
D --&amp;gt;|误差指数发散| E[pha = 0.000000]
&lt;/code&gt;&lt;/pre&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;
核心洞察：**RNN 的误差累积是架构性问题，不是校准问题。**
--&amp;gt;

### **4. RVM INT8 — 混合量化尝试**

&amp;lt;!-- 填入：
- 方案：INT8 编解码 + FP16 r-state（保留递归状态精度）
- 阻断：被 SDK v2.3.2 bug 阻断（SE Block KeyError &amp;#39;593&amp;#39;）
- 根因：rknn-toolkit2 v2.3.2 的 quant_optimizer.py._p_adjust_tanh_sigmoid() 对 SE Block 的 MatMul→Sigmoid tensor key 处理有缺陷
- 进展：v2.4.0 修复了 quant_optimizer，但 hybrid_step2 完整验证未完成
- 参考 PKB summarize-MR2-ending.md §2.2
--&amp;gt;

### **5. ConvGRU INT8 vs MODNet INT8 对比**

&amp;lt;!-- 填入：对比表（参考 PKB summarize-MR2-ending.md §2.3）：

| 维度 | RVM (ConvGRU) | MODNet (纯 CNN) |
|------|---------------|-----------------|
| INT8 精度 | ❌ cosine=0.000 | ✅ cosine=0.999 |
| 误差累积 | 有（帧间 r-state）| 无（每帧独立）|
| 混合量化可行性 | ❌ SDK bug 阻断 | ✅ 不需要 |
| FPS 上限 | ~16.7 | ~30-40 |
--&amp;gt;

### **6. Value of This Exploration**

&amp;lt;!-- 填入：这一章的核心价值：

&amp;#34;用实验证明了一条路走不通&amp;#34;本身就是工程判断力。

具体价值：
1. 避免了在错误方向上继续投入（RVM INT8）
2. 定量证明了 RNN 在 NPU 上的架构性限制
3. 为项目方向决策提供了数据支撑（回到 MODNet）
4. 发现了 SDK bug，对社区有参考价值

这个发现不是&amp;#34;失败&amp;#34;，而是&amp;#34;用最小代价获得了最关键的判断&amp;#34;。
--&amp;gt;

### **7. Decision: Back to MODNet**

&amp;lt;!-- 填入：基于以上实验，做出的决策：

1. RVM 架构性 FPS 天花板 16.7，无法突破 30 FPS
2. ConvGRU INT8 精度崩溃，混合量化被 SDK bug 阻断
3. MODNet 纯 CNN 无帧间依赖，INT8 可行，理论 30+ FPS
4. 决定回到 MODNet 路线，继续 INT8 + 流水线并行
--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Chapter 7: 复盘与反思</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage7-retrospective/</link><pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/stage7-retrospective/</guid><description>&lt;script type="module"&gt;
 import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
&lt;/script&gt;
&lt;h3 id="chapter-7-retrospective--lessons-from-an-edge-ai-deployment-journey"&gt;&lt;strong&gt;Chapter 7: Retrospective — Lessons from an Edge AI Deployment Journey&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;Project Attribute&lt;/th&gt;
					&lt;th style="text-align: left"&gt;Details&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Project Name&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Helmsman — Retrospective&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Date&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2026-01 ~ 2026-06（5 个月）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;Key Personnel&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h3 id="1-project-timeline"&gt;&lt;strong&gt;1. Project Timeline&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：完整时间线概览（参考 PKB _DASHBOARD.md 详细时间线）：

```mermaid
gantt
 title Helmsman Project Timeline
 dateFormat YYYY-MM-DD
 section Foundation
 F0 Reconnaissance :2026-01-01, 30d
 F1 Golden Reference :2026-02-01, 30d
 section Round 1 MODNet
 MR1 BN Surgery + Training :2026-03-12, 7d
 DR1 GF Experiments :2026-04-02, 4d
 DR1 RKNN FP16 :2026-04-02, 4d
 DR1 INT8 (paused) :2026-04-06, 1d
 section Round 2 RVM
 MR2 Gate-0 + ONNX :2026-04-09, 2d
 MR2 RKNN FP16 + C++ :2026-04-10, 4d
 MR2 INT8 Quantization :2026-04-13, 2d
 MR2 Speed Optimization :2026-04-15, 54d
```

--&gt;
&lt;h3 id="2-key-decisions"&gt;&lt;strong&gt;2. Key Decisions&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：4 个关键决策，每个用"背景→选项→决策→结果"的格式：

**Decision 1: BN 手术而非换模型**
- 背景：InstanceNorm 导致 NPU 量化崩溃
- 选项：A) 换一个没有 IN 的模型 B) 手术替换 IN→BN C) 接受 CPU fallback
- 决策：B，因为 MODNet 的架构最适合 NPU，不值得换
- 结果：Val L1=0.0086，NPU 原生支持 ✅

**Decision 2: Graph Surgery 而非接受性能损失**
**Decision 3: DMA Zero-Copy 而非优化 CPU 代码**
**Decision 4: 放弃 RVM 回到 MODNet**
--&gt;
&lt;h3 id="3-what-went-right"&gt;&lt;strong&gt;3. What Went Right&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
1. **Golden Reference 方法论**：先在 x86 上对齐，再移植到板端。避免了"板端结果不对但不知道是模型问题还是代码问题"的困境。
2. **层级计时系统**：ScopedTimer + StageAccumulator，精确到每个子阶段的 min/avg/max。避免了凭直觉优化。
3. **PKB 文档体系**：83 个文件，可追溯所有决策。10 年后顺着时间线读下去，能复现所有研究/思考/bug/解决过程。
4. **渐进式架构**：先跑通再优化，先同步再流水线。没有一开始就过度设计。
--&gt;
&lt;h3 id="4-what-i"&gt;&lt;strong&gt;4. What I&amp;rsquo;d Do Differently&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：
1. **更早做 profiling**：NEON 优化花了时间但不是瓶颈，如果先 profiling 就不会走这条弯路。
2. **更早验证 INT8 可行性**：RVM 的 INT8 探索可以更早做，早点发现 ConvGRU 的死局就能早点转向。
3. **可能直接选 MODNet**：RVM 的质量确实更好，但在嵌入式场景下，FPS 和 INT8 可行性比质量更重要。
--&gt;
&lt;h3 id="5-skills-gained"&gt;&lt;strong&gt;5. Skills Gained&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：技能成长表格：

| 技能 | 具体内容 | 从哪学到 |
|------|---------|---------|
| 端侧 AI 部署 | 模型→ONNX→RKNN→NPU 推理全链路 | 整个项目 |
| C++ 系统工程 | NVI 模式、工厂模式、RAII、并发 | Pipeline 工程 |
| 硬件调试 | MPP、RGA、DMA、NPU | 五层 Bug 剥洋葱 |
| 性能分析 | 精确 profiling、NEON、白盒分析 | 速度优化 |
| 模型手术 | IBNorm→BN、Graph Surgery | Round 1 + 2 |
| 量化工程 | INT8 校准、混合量化、SDK bug 分析 | INT8 探索 |
--&gt;
&lt;h3 id="6-reusable-assets"&gt;&lt;strong&gt;6. Reusable Assets&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：（参考 PKB summarize-MR2-ending.md §四）

**代码资产**：

| 资产 | 说明 |
|------|------|
| ArcFoundry 框架 | YAML 驱动的 RKNN 转换，支持 graph surgery |
| NEON SIMD 库 | FP32↔FP16 转换，2.9× 加速，header-only |
| DmaKit | RAII DMA buffer 分配 |
| MppDecoder | H.264 硬件解码，dmabuf fd 输出 |
| Guided Filter | boxFilter 纯 OpenCV，可配参数 |
| RKNN Zero-Copy Engine | DMA buffer 管理，5-in/6-out 多 tensor |
| ScopedTimer + StageAccumulator | 层级计时系统 |
| GraphSurgeon 策略 | 配置驱动 ONNX 图手术 |

**知识资产**：

| 发现 | 价值 |
|------|------|
| InputOperator 是 runtime 内部开销 | 避免无效优化方向 |
| Cache flush 仅 0.07ms | 排除 cache 优化方向 |
| DDR 非瓶颈（~20% 利用率）| INT8 带宽收益有限 |
| NPU 算子融合仅 2-3 层 | 理解 RKNN 性能天花板 |
| ConvGRU INT8 误差指数发散 | RNN 量化是死路 |
| librknnrt 五大性能根因 | 定量理解 RKNN 天花板 |
--&gt;
&lt;h3 id="7-what"&gt;&lt;strong&gt;7. What&amp;rsquo;s Next&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：如果继续这个项目，下一步是什么：

1. **MODNet INT8 量化**：Q.2~Q.7 待续，目标 INT8 + 流水线并行 → 30+ FPS
2. **三级流水线**：decode // preprocess+infer // backend，理论吞吐量翻倍
3. **知识蒸馏**：恢复发丝边缘细节
4. **IPC 服务化**：V4L2 · MPP/RGA · dma_buf IPC · C/S 架构

但项目因公司战略调整终止，技术路线已验证可行。
--&gt;
&lt;h3 id="8-closing-thoughts"&gt;&lt;strong&gt;8. Closing Thoughts&lt;/strong&gt;&lt;/h3&gt;
&lt;!-- 填入：最后的总结。这个项目教会你什么？一句话概括你的成长。比如：

"从一个只会 import ultralytics 跑 YOLO 的人，变成了一个能从模型手术到 NPU 推理全栈打通的系统工程师。"

或者更深层的收获：工程判断力 —— 知道什么时候该坚持，什么时候该放弃，什么时候该先 profiling 再动手。
--&gt;</description></item><item><title>Section 8.1: Orin NX 上给 RVM 测 FPS 基线</title><link>https://potterwhite.github.io/portfolio/edge-ai/helmsman/section8.1-orin-nx-deployment/</link><pubDate>Fri, 28 Aug 2026 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/helmsman/section8.1-orin-nx-deployment/</guid><description>&lt;h1 id="orin-nx-上给-rvm-测-fps-基线"&gt;Orin NX 上给 RVM 测 FPS 基线&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;状态&lt;/strong&gt;：骨架，待填肉。数字已核对，散文全部待写。
&lt;strong&gt;归属&lt;/strong&gt;：Helmsman / CUDA 平台线（与现有 7 章 Rockchip 线并列，勿插入编号）
&lt;strong&gt;数据来源&lt;/strong&gt;：&lt;code&gt;deploy/cuda/day3-docker-pytorch-and-rvm-fp32.md&lt;/code&gt;（2026-08-26/27 实测）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="--流水账"&gt;〇 · 流水账&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;镜像选型 → 容器起来 → CUDA 可用性验证 → RVM 仓库 + 权重就位&lt;/li&gt;
&lt;li&gt;出图成功：363 帧 1080p，vlc 确认抠图正常、发丝边缘干净&lt;/li&gt;
&lt;li&gt;端到端 &lt;code&gt;1.83 it/s&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- 填肉：镜像 tag 怎么选的、踩了哪些环境坑（cv2/X11 那些扔附录，别进正文） --&gt;
&lt;p&gt;ClaudeCode用来建立课程，尤其是自己不太熟悉的领域，效果不错。&lt;/p&gt;
&lt;p&gt;虽然RVM的模型部署对我来说并不陌生了，但是毕竟Jetson是陌生的，所以最初的基础还是CC给我建立的。&lt;/p&gt;
&lt;p&gt;拿到硬件的检查，打印外壳，模组压力测试，温度曲线，GPU使用率曲线等都属于BSP的内容，我在此就以BSP环节都完成为起点，直接展开RVM的部署记载。&lt;/p&gt;
&lt;h3 id="第一件事选择什么容器镜像"&gt;第一件事，选择什么容器镜像&lt;/h3&gt;
&lt;p&gt;虽然我觉得在arm板上再部署docker,对于最终性能的损耗总会有担心，但AI给的回答是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;现在以快速上线为第一，而英伟达给的容器镜像就把这部分依赖环境都给建立好，所以用容器的学习成本是小于投入时间研究环境的代价的。&lt;/li&gt;
&lt;li&gt;容器不会留到最终生产阶段，所以性能的微弱影响可以在此忽略不计。&lt;/li&gt;
&lt;li&gt;Jetson上部署容器，以及nvidia-container-toolkit关系是什么，能用docker官网给出的&lt;a href="https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository" target="_blank" rel="noopener"&gt;安装命令&lt;/a&gt;吗？（反正都是apt去做）为什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;带着这些问题，我决定跟着课程走。第一件事，就是选择什么镜像呢？&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;1. 打开 https://catalog.ngc.nvidia.com/
 ↓
2. 左侧筛选栏先勾 【Containers】 ← ⭐ 第一下就勾这个
 ↓ （NGC 上还有 Models / Resources / Helm Charts / Collections，
 ↓ 跟找镜像无关，勾掉之后页面立刻清爽）
 ↓
3. 搜索框输 &amp;#34;pytorch&amp;#34; ← ⭐ 只输容器名，永远不要输版本号
 ↓
4. 点进 【PyTorch】 那张卡片（因为rvm的模型用的就是pytorch）
 ↓
5. 点页面上的 【Tags】 标签页 ← ⭐ 关键就是这一下，tag 只在这里
 ↓
6. 在 tag 列表里找名字带 -igpu 的
 ↓
7. 有N个带-igpu的镜像，选择哪一个得看pytorch对应的cuda版本
 a. ssh到jetson,输入&amp;#39;ls -lhat /usr/local/cuda-*&amp;#39;，此处我显示出是cuda-12.6。因此接下来就是要找到对应cuda12.6的pytorch-xx-igpu镜像
 b. 打开 https://docs.nvidia.com/deeplearning/frameworks/pytorch-release-notes/
 c. 左侧目录点 &amp;#34;PyTorch Release 24.12&amp;#34;
 （或直接改 URL：.../rel-24-12.html ← 把年月换成我要查的那个版本）
 d. 页面开头 &amp;#34;This container image contains...&amp;#34; 那段，看两行：
 NVIDIA CUDA xxxx ← ⭐ 这个跟宿主比
 PyTorch 2.6.yyyy
 e. 如果不匹配，就继续回到b,寻找其他pytorch的版本，直到找到为止；
 如果已找到匹配，那就记下这个版本号，例如24.12

8. 回到5的tags标签页，找到你要的标签，例如上面举例的24.12，然后用每行右边的 【Copy】 按钮取完整 pull 路径（别手打，容易出错）
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="第二件事-初始化开发环境"&gt;第二件事. 初始化开发环境&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87"&gt;cd&lt;/span&gt; /workspace/rvm
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/PeterL1n/RobustVideoMatting.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#204a87"&gt;cd&lt;/span&gt; RobustVideoMatting.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# 下预训练权重&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://github.com/PeterL1n/RobustVideoMatting/releases/download/v1.0.0/rvm_mobilenetv3.pth &lt;span style="color:#4e9a06"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -O /workspace/rvm/weights/rvm_mobilenetv3.pth
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#8f5902;font-style:italic"&gt;# 依赖&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pip3 install &lt;span style="color:#000"&gt;numpy&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;1.26.4 &lt;span style="color:#000"&gt;av&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;12.3.0 &lt;span style="color:#000"&gt;pims&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;0.7 &lt;span style="color:#000"&gt;slicerator&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;1.1.0 &lt;span style="color:#000"&gt;imageio&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;2.34.2 &lt;span style="color:#000"&gt;tqdm&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;4.67.1 &lt;span style="color:#000"&gt;tifffile&lt;/span&gt;&lt;span style="color:#ce5c00;font-weight:bold"&gt;==&lt;/span&gt;2024.8.30 --proxy&lt;span style="color:#ce5c00;font-weight:bold"&gt;=&lt;/span&gt;&lt;span style="color:#4e9a06"&gt;&amp;#34;http://192.168.3.164:7890&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这些依赖都在我的docker of jetson里跑通了。&lt;/p&gt;</description></item></channel></rss>