<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sherpa(Next Gen Kaldi)部署在Rockchip的不同SOC上 on Potter的个人笔记</title><link>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/</link><description>Recent content in Sherpa(Next Gen Kaldi)部署在Rockchip的不同SOC上 on Potter的个人笔记</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Sat, 27 Sep 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/index.xml" rel="self" type="application/rss+xml"/><item><title>第一章：RK3588S平台 Sherpa ASR 模块化部署(C/S架构)</title><link>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage1-integration/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage1-integration/</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;h1 id="项目复盘报告-after-action-review---优化版"&gt;&lt;strong&gt;项目复盘报告 (After-Action Review) - 优化版&lt;/strong&gt;&lt;/h1&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;项目属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;内容&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;项目名称&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;RK3588S平台 Sherpa ASR 模块化部署(C/S架构)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;项目周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-04-25 ~ 2025-06-24&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;复盘日期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-06-24&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;核心人员&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;Potter White&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;总计工时&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;34 个工作日&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="1-目标回顾-what-was-supposed-to-happen"&gt;1. 目标回顾 (What was supposed to happen?)&lt;/h2&gt;
&lt;h3 id="11-项目目标"&gt;1.1 项目目标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心功能：&lt;/strong&gt; 构建一个生产级的、支持高并发的离线语音识别（ASR）服务。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能预期：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;显性要求：&lt;/strong&gt; 实时率 (RTF) 显著优于 1.0。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隐性要求：&lt;/strong&gt; 推理延迟在可接受范围内（目标 &amp;lt; 1秒），用户体验流畅。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;质量与稳定性预期：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;显性要求：&lt;/strong&gt; 服务可模块化部署，与主应用解耦。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隐性要求：&lt;/strong&gt; 7x24 小时稳定运行，无内存泄漏、死锁或数据竞争。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="12-初始方案与假设"&gt;1.2 初始方案与假设&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心技术栈：&lt;/strong&gt; C++17, CMake, &lt;code&gt;std::thread&lt;/code&gt;, 自研 LibSocket(IPC)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;架构演进思路：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;阶段一 (原型驱动)：&lt;/strong&gt; 鉴于技术选型不确定，初期采用快速原型法，验证核心技术（Whisper vs. Sherpa）的可行性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;阶段二 (架构定型)：&lt;/strong&gt; 原型验证成功后，确立 &lt;strong&gt;IPC + C/S 架构&lt;/strong&gt;。该设计旨在实现 ASR 服务的独立部署、测试和升级，降低系统耦合度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键假设 (后被证伪)：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;假设 1 (错误)：&lt;/strong&gt; &lt;strong&gt;模型加载成本低。&lt;/strong&gt; 误认为可以为每个新连接的会话动态加载 ASR 模型，而无需考虑其高昂的 I/O 和内存开销。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;假设 2 (错误)：&lt;/strong&gt; &lt;strong&gt;并发管理简单。&lt;/strong&gt; 误认为简单的线程分离 (&lt;code&gt;std::thread::detach&lt;/code&gt;) 或缺乏同步机制的线程管理足以应对生产环境的并发请求。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="2-实际结果-what-actually-happened"&gt;2. 实际结果 (What actually happened?)&lt;/h2&gt;
&lt;h3 id="21-最终成果"&gt;2.1 最终成果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;性能表现：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实时率 (RTF) 达到 0.2&lt;/strong&gt;，意味着处理1秒音频仅需0.2秒，性能远超预期，为系统提供了充足的性能裕量。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能完整性：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实现了非追加式（Non-Appending）文本流输出&lt;/strong&gt;，显著提升了实时字幕的用户体验。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成功构建了模块化的 C/S 架构&lt;/strong&gt;，ASR 服务作为独立的 Server 进程运行，稳定性高，易于维护。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;通过 &lt;code&gt;helgrind&lt;/code&gt; 压力测试&lt;/strong&gt;，系统性地识别并修复了所有数据竞争与死锁隐患，保证了并发安全性。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;可复用资产：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;封装了三个高质量的 C++ 库：&lt;/strong&gt; &lt;code&gt;LibASR&lt;/code&gt;, &lt;code&gt;LibSocket&lt;/code&gt;, &lt;code&gt;LibUtils&lt;/code&gt;，实现了功能的高度内聚和代码复用。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="22-关键事件与过程时间线"&gt;2.2 关键事件与过程（时间线）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;迭代一 (技术预研 - 4天):&lt;/strong&gt; 调研 Whisper，因其转换部署流程复杂而转向 Sherpa。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代二 (原型验证 - 4天):&lt;/strong&gt; 成功运行 Sherpa C++ Demo，解决了硬件环境（ALSA 配置）问题，验证了核心方案可行性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代三 (核心逻辑开发 - 7天):&lt;/strong&gt; 重构 Demo 代码，初步实现 wav 和 mic 输入的解码逻辑，为后续开发奠定基础。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代四 (高级功能探索 - 6天):&lt;/strong&gt; 成功集成 VAD (Voice Activity Detection) 功能，并解决了关键的用户体验问题——&lt;strong&gt;如何打断追加式输出&lt;/strong&gt;，最终通过 Endpointing 机制部分解决。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代五 (架构重构与库封装 - 5天):&lt;/strong&gt; &lt;strong&gt;项目关键转折点&lt;/strong&gt;。将原型代码重构为三个独立的库（ASR、Socket、Utils），实现了代码的模块化、正规化和高复用性。此阶段深入掌握了 POSIX Socket API 和单例（Singleton）模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代六 (集成与测试 - 6.5天):&lt;/strong&gt; 将库与 App 层集成，并构建了全面的测试体系。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解决了服务端连接处理的生命周期问题&lt;/strong&gt;，实现了对多客户端连接的健壮处理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;优化了模型加载策略&lt;/strong&gt;，意识到为每个 Worker 加载模型的性能瓶颈（待优化项）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;构建了 gtest 单元测试、集成测试和压力测试&lt;/strong&gt;，系统性地保障了代码质量。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;迭代七 (并发调试与加固 - 1.5天):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;Valgrind&lt;/code&gt; 和 &lt;code&gt;helgrind&lt;/code&gt; 进行深度内存与并发问题分析。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定位并修复了关键的并发 bug&lt;/strong&gt;，为共享资源（如 Worker 列表、Socket 连接）添加了互斥锁 (&lt;code&gt;std::lock_guard&lt;/code&gt;) 保护。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="3-差异分析根因探究-why-was-there-a-difference"&gt;3. 差异分析：根因探究 (Why was there a difference?)&lt;/h2&gt;
&lt;h3 id="31-成功之处-what-went-well-and-why"&gt;3.1 成功之处 (What went well, and why?)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;成功点 1：采用了面向对象的结构化并发设计。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 将 ASR 任务 (&lt;code&gt;ASRTaskSherpa&lt;/code&gt;) 与其执行线程 (&lt;code&gt;std::thread&lt;/code&gt;) 封装为统一的生命周期管理单元 (&lt;code&gt;TaskHandler&lt;/code&gt;)，并用 &lt;code&gt;std::vector&lt;/code&gt; 统一管理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; 这本质上是&lt;strong&gt;应用了 RAII (Resource Acquisition Is Initialization) 思想来管理线程资源&lt;/strong&gt;。通过将线程的生命周期与任务对象的生命周期绑定，避免了手动管理线程 &lt;code&gt;join&lt;/code&gt; 或 &lt;code&gt;detach&lt;/code&gt; 的复杂性和风险，从设计上根除了资源泄漏和“僵尸线程”问题。&lt;strong&gt;这从“面向过程”的线程管理思路，跃迁到了“面向对象”的并发实体管理，极大地降低了心智负担和出错率。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;成功点 2：果断进行架构重构，实现了高度模块化。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 在项目中期，将耦合在一起的原型代码拆分为三个独立的库。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; &lt;strong&gt;认识到底层能力的稳定性和可复用性是上层业务逻辑快速迭代的基础。&lt;/strong&gt; 通过封装基础库（通信、日志、ASR 核心 API），使得主应用（App）的逻辑变得极为清晰，只专注于业务流程编排。这体现了**“关注点分离” (Separation of Concerns)** 的核心设计原则，是项目从“能用”到“好用、易维护”的关键一步。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="32-不足之处-what-could-be-improved-and-why"&gt;3.2 不足之处 (What could be improved, and why?)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;问题点 1：对阻塞式 I/O 的并发中断处理考虑不周，导致无法优雅停机。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 在主线程中尝试通过 &lt;code&gt;stop_flag_&lt;/code&gt; 停止工作线程时，若工作线程正阻塞在 &lt;code&gt;::recv()&lt;/code&gt; 上，则线程无法响应停止信号，导致 &lt;code&gt;join()&lt;/code&gt; 无限等待，程序卡死。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; &lt;strong&gt;缺乏对“异步中断”机制的理解。&lt;/strong&gt; &lt;code&gt;atomic&lt;/code&gt; 标志位只能在线程的轮询逻辑中被检查，但无法唤醒一个深度睡眠在内核态（如 &lt;code&gt;recv&lt;/code&gt; 阻塞）的线程。这是同步编程思维在异步并发环境下的典型误用。&lt;strong&gt;正确的解决方案应采用非阻塞 I/O + I/O 多路复用（如 &lt;code&gt;epoll&lt;/code&gt;, &lt;code&gt;select&lt;/code&gt;）或为 socket 设置超时 (&lt;code&gt;setsockopt&lt;/code&gt;)，让 &lt;code&gt;recv&lt;/code&gt; 能在指定时间后返回，从而有机会检查 &lt;code&gt;stop_flag_&lt;/code&gt;。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问题点 2：在多线程环境下，对共享资源的所有权和访问控制不明确。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 在主线程的 &lt;code&gt;stop_me()&lt;/code&gt; 中直接操作工作线程正在使用的 &lt;code&gt;client_&lt;/code&gt; (&lt;code&gt;unique_ptr&lt;/code&gt;)，引发 &lt;code&gt;helgrind&lt;/code&gt; 报数据竞争。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; &lt;strong&gt;对 C++ 内存所有权和线程安全边界的认知存在盲区。&lt;/strong&gt; 即使是 &lt;code&gt;unique_ptr&lt;/code&gt; 这种看似安全的智能指针，其&lt;strong&gt;指针本身&lt;/strong&gt;（而非其指向的对象）在多个线程间共享和修改时，同样需要同步机制（如 &lt;code&gt;mutex&lt;/code&gt;）来保护。&lt;strong&gt;问题的核心在于，任何跨线程共享的可变状态，都必须被显式地保护起来，这是并发编程的铁律。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;架构待优化点 1：模型加载策略与会话生命周期耦合。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 每个新的客户端连接都会触发一次模型的重新加载，造成巨大的 I/O 和性能开销。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; &lt;strong&gt;未能将“重量级资源”（模型）与“轻量级会话”（客户端连接）的生命周期分离&lt;/strong&gt;。这是初期设计假设错误（假设1）的直接后果。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;架构待优化点 2：缺乏对不同 ASR 模型的抽象。&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;现象：&lt;/strong&gt; 当前的 ASRTaskSherpa 类与 Sherpa 的具体实现强耦合，若要切换到其他 ASR 方案（如 Whisper），需要大量修改代码。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本原因：&lt;/strong&gt; 未能应用**“面向接口编程”**的设计思想。缺乏一个抽象的 IASRTask 接口层。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="4-行动计划未来如何做-what-will-we-do-next-time"&gt;4. 行动计划：未来如何做 (What will we do next time?)&lt;/h2&gt;
&lt;h3 id="41-个人能力提升-personal-growth"&gt;4.1 个人能力提升 (Personal Growth)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;技术栈深化：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C++ 并发编程：&lt;/strong&gt; 系统学习 &lt;code&gt;std::future&lt;/code&gt;, &lt;code&gt;std::promise&lt;/code&gt;, &lt;code&gt;std::async&lt;/code&gt;，掌握更现代的异步任务编程范式。深入研究非阻塞 I/O 与 &lt;code&gt;epoll&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设计模式：&lt;/strong&gt; 将本次实践的“建造者模式 (Builder)”和“单例模式 (Singleton)”内化，并主动学习“策略模式”、“观察者模式”等，以应对更复杂的业务场景。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;C++ 核心准则：&lt;/strong&gt; 深入理解“RAII”、“零规则 (Rule of Zero/Five)”，让代码天然地安全和高效。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;思维模式转变：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;并发优先思维：&lt;/strong&gt; 在设计任何类或函数时，都要先问一句：“这个对象或数据会被多个线程访问吗？”将线程安全作为一等公民来考虑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设计先于实现：&lt;/strong&gt; 对于复杂模块，强制要求自己先绘制简单的时序图、状态机图或组件交互图，梳理清楚生命周期和数据流，再开始编码。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="42-流程与规范改进-process--standards-improvement"&gt;4.2 流程与规范改进 (Process &amp;amp; Standards Improvement)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;强制性设计关口：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;并发设计评审：&lt;/strong&gt; 对于任何涉及多线程的模块，必须输出一份简要的&lt;strong&gt;并发模型说明&lt;/strong&gt;，明确：共享资源、同步机制（用什么锁）、线程生命周期管理策略。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动化质量保障：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;集成静态/动态分析工具：&lt;/strong&gt; 将 &lt;code&gt;Clang-Tidy&lt;/code&gt; (静态分析)、&lt;code&gt;ThreadSanitizer&lt;/code&gt; (数据竞争检测)、&lt;code&gt;MemorySanitizer&lt;/code&gt; (内存问题检测) 集成到 CMake 和 CI/CD 流程中，实现问题的早期自动化发现。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;编码规范标准化：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;建立团队统一的 C++ 编码规范&lt;/strong&gt; (可基于 Google Style Guide)，并使用 &lt;code&gt;clang-format&lt;/code&gt; 强制执行，覆盖命名、头文件管理、注释等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目录结构规范：&lt;/strong&gt; 固化 &lt;code&gt;include/&lt;/code&gt;, &lt;code&gt;src/&lt;/code&gt;, &lt;code&gt;test/&lt;/code&gt;, &lt;code&gt;libs/&lt;/code&gt; 等项目结构，并推广为团队的项目模板。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="43-知识沉淀与复用-knowledge-management--reuse"&gt;4.3 知识沉淀与复用 (Knowledge Management &amp;amp; Reuse)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;资产化成果：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;C++ 服务器项目模板：&lt;/strong&gt; 将本次项目的结构、CMake 配置、日志库、测试框架集成为一个 Git 模板仓库，新项目可一键启动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档化最佳实践：&lt;/strong&gt; 撰写一份 “C++ 并发服务器常见陷阱与最佳实践” 的内部文档，包含本次复盘中关于优雅停机、数据竞争的案例分析。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分享计划：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;内部技术分享：&lt;/strong&gt; 组织一次以“从单线程到高并发：一个 C++ ASR 服务器的演进与陷阱”为题的技术分享会。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;发布个人博客/文章：&lt;/strong&gt; 将本次复盘的精华部分（特别是“差异分析”和“行动计划”）整理成文章，分享到技术社区。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>第二章：RV1126平台 Sherpa ASR 部署技术评估与实现</title><link>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage2-porting/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage2-porting/</guid><description>&lt;h3 id="heading"&gt;&lt;strong&gt;[项目复盘报告] RV1126平台 Sherpa ASR 部署技术评估与实现&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;项目属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;内容&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;项目名称&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;第二部分：RV1126平台 Sherpa ASR 部署技术评估与实现&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;项目周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-07-26 ~ 2025-08-06 (估算)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;项目用时&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;50.17小时 (约6.3人天)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;复盘日期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-08-20&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;核心人员&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-项目背景与初始目标"&gt;&lt;strong&gt;1. 项目背景与初始目标&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="11-项目启动背景"&gt;&lt;strong&gt;1.1 项目启动背景&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;本项目旨在为公司产品线在 Rockchip RV1126b 嵌入式平台上集成高性能的实时语音识别（ASR）功能。鉴于 V1.0 项目在 RK3588s 平台上成功部署 &lt;code&gt;sherpa-onnx&lt;/code&gt; 并利用 NPU 取得了卓越性能，本次项目的初始规划旨在复刻这一成功路径，以期在成本更低的 RV1126b 平台上实现兼具性能与成本效益的 AI 功能落地。&lt;/p&gt;
&lt;h4 id="12-核心技术目标"&gt;&lt;strong&gt;1.2 核心技术目标&lt;/strong&gt;&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;功能目标：&lt;/strong&gt; 成功部署 Sherpa ASR 引擎，并将其集成为一个稳定可靠的服务模块。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;性能目标：&lt;/strong&gt; 实现远低于 1.0 的实时率（RTF），确保实时字幕等功能的流畅用户体验。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="13-初始技术方案与假设"&gt;&lt;strong&gt;1.3 初始技术方案与假设&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;基于前序项目的经验，我制定了以 &lt;code&gt;sherpa-onnx&lt;/code&gt; 框架为核心的技术方案。该方案的优势在于能够直接利用 Rockchip 平台的 RKNN 工具链进行 NPU 硬件加速，理论上是性能最优解。此方案建立在以下关键假设之上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;假设一：工具链兼容性。&lt;/strong&gt; 我假设 &lt;code&gt;sherpa-onnx&lt;/code&gt; 的源码可以与 RV1126b 平台提供的原生交叉编译工具链（GCC 8.3）兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;假设二：SDK API兼容性。&lt;/strong&gt; 我假设 RV1126b 平台搭载的 &lt;code&gt;librknnrt&lt;/code&gt; 运行时库，其 API 版本能够满足 &lt;code&gt;sherpa-onnx&lt;/code&gt; 框架中对 RKNN 功能的调用需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然而，在项目推进过程中，上述两个核心假设均被证伪，迫使项目进行了重大的技术路径调整。&lt;/p&gt;</description></item><item><title>第三章：RV1126BP平台 Sherpa ASR RKNN自主模型转换</title><link>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage3-conversion/</link><pubDate>Thu, 21 Aug 2025 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage3-conversion/</guid><description>&lt;h3 id="heading"&gt;&lt;strong&gt;[项目复盘报告 V3.0] 自主模型转换：攻克动态ONNX模型至RKNN的技术难题&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;项目属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;内容&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;项目名称&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;第三部分：RV1126BP平台 Sherpa ASR RKNN自主模型转换&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;项目周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-07-31 ~ 2025-08-09 (估算)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;项目用时&lt;/td&gt;
					&lt;td style="text-align: left"&gt;31.5(约3.9人天)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;复盘日期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-08-20&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;核心人员&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-项目背景与启动"&gt;&lt;strong&gt;1. 项目背景与启动&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;在 V2.0 项目中，我们验证了 &lt;code&gt;sherpa-onnx&lt;/code&gt; 框架因目标平台 RKNN SDK 版本过低而无法直接使用 NPU 加速，同时 &lt;code&gt;sherpa-ncnn&lt;/code&gt; 的纯 CPU 方案也已达到性能瓶颈。因此，为了充分利用 RV1126b 平台的 NPU 硬件，本项目（V3.0）的核心目标是&lt;strong&gt;绕开 &lt;code&gt;sherpa-onnx&lt;/code&gt; 的编译限制，自主完成从 ONNX 模型到 RKNN 模型的转换工作&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这项工作的起点，是处理 Sherpa ASR 模型中普遍存在的动态输入维度问题。&lt;/p&gt;
&lt;h3 id="2-基础问题分析与通用转换策略"&gt;&lt;strong&gt;2. 基础问题分析与通用转换策略&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="21-理解动态维度"&gt;&lt;strong&gt;2.1 理解动态维度 &lt;code&gt;[N, ...]&lt;/code&gt;&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;在 ONNX 模型中，维度 &lt;code&gt;N&lt;/code&gt; 通常作为一个占位符，代表动态的批处理大小（Batch Size）。例如，一个 &lt;code&gt;[N, 39, 80]&lt;/code&gt; 的输入形状意味着模型可以一次性处理 &lt;code&gt;N&lt;/code&gt; 个输入样本。然而，为了在嵌入式 NPU 上实现最高效的运算，RKNN 工具链通常要求模型的输入形状是固定的、静态的。&lt;/p&gt;</description></item><item><title>第五章：嵌入式平台 (RV1126B) 流式 ASR 模型 (Zipformer) INT8 端到端量化与部署</title><link>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage5-quantization/</link><pubDate>Sat, 27 Sep 2025 00:00:00 +0000</pubDate><guid>https://potterwhite.github.io/portfolio/edge-ai/sherpa-deployed-rockchip/stage5-quantization/</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="heading"&gt;&lt;strong&gt;[项目复盘报告 V5.0] 嵌入式平台 (RV1126B) 流式 ASR 模型 (Zipformer) INT8 端到端量化与部署&lt;/strong&gt;&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th style="text-align: left"&gt;项目属性&lt;/th&gt;
					&lt;th style="text-align: left"&gt;内容&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;项目名称&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;第五部分：RV1126BP平台 Sherpa ASR RKNN量化&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;项目周期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-08-21 ~ 2025-09-23&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;项目用时&lt;/td&gt;
					&lt;td style="text-align: left"&gt;40(约5人天)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;复盘日期&lt;/strong&gt;&lt;/td&gt;
					&lt;td style="text-align: left"&gt;2025-09-27&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;&lt;strong&gt;核心人员&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-objective"&gt;&lt;strong&gt;1. 项目目标 (Project Objective)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;为基于 Rockchip RV1126B SoC 的嵌入式设备，将一个 &lt;code&gt;FP32&lt;/code&gt; 精度的流式 Zipformer ASR (Automatic Speech Recognition) ONNX 模型，转换为 &lt;code&gt;INT8&lt;/code&gt; 精度的 RKNN 模型，并在 &lt;code&gt;sherpa-onnx&lt;/code&gt; C++ 推理框架中完成部署与验证，以满足低延迟和低功耗的运行要求。&lt;/p&gt;
&lt;h3 id="2-执行方法与流程-methodology--workflow"&gt;&lt;strong&gt;2. 执行方法与流程 (Methodology &amp;amp; Workflow)&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;本项目采用了一套系统性的方法，覆盖从模型分析、运行时环境改造、量化数据生成到最终模型验证的全过程。&lt;/p&gt;
&lt;pre class="mermaid"&gt;graph TD
 classDef main fill:#2c3e50,color:white,stroke:#8e9eab;
 classDef task fill:#4b3e58,color:white,stroke:#b8a3d3;
 classDef check fill:#27ae60,color:white,stroke:#88d1a1;
 classDef fail fill:#c0392b,color:white,stroke:#e69a93;
 classDef success fill:#16a085,color:white,stroke:#72d6c1;
 classDef note fill:#f39c12,color:white,stroke:#f8c471;

 S[&amp;lt;b&amp;gt;开始: FP32 ONNX 模型&amp;lt;/b&amp;gt;]:::main
 A[&amp;#34;&amp;lt;div style=&amp;#39;text-align:left; padding:10px;&amp;#39;&amp;gt;&amp;lt;b&amp;gt;1. 初始模型分析与转换&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;- 使用预量化的 INT8 ONNX 模型进行直接转换&amp;lt;/div&amp;gt;&amp;#34;]:::task

 %% --- THIS IS THE MISSING LINE THAT FIXES THE CONNECTION ---
 S --&amp;gt; A

 A --&amp;gt; R1{&amp;#34;&amp;lt;div style=&amp;#39;text-align:center&amp;#39;&amp;gt;转换是否成功?&amp;lt;/div&amp;gt;&amp;#34;}:::check
 R1 -- &amp;#34;否: 存在 `DynamicQuantizeLinear` 算子&amp;#34; --&amp;gt; B

 B[&amp;#34;&amp;lt;div style=&amp;#39;text-align:left; padding:10px;&amp;#39;&amp;gt;&amp;lt;b&amp;gt;2. C&amp;#43;&amp;#43; 运行时适配&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;- 分析 `sherpa-onnx` RKNN 后端代码&amp;lt;br&amp;gt;- 增加对 `RKNN_TENSOR_INT8` 类型的处理分支&amp;lt;br&amp;gt;- 实现 INT8 输出到 FP32 的手动反量化逻辑&amp;lt;/div&amp;gt;&amp;#34;]:::task
 B --&amp;gt; C

 C[&amp;#34;&amp;lt;div style=&amp;#39;text-align:left; padding:10px;&amp;#39;&amp;gt;&amp;lt;b&amp;gt;3. 校准数据集迭代&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;3.1 (快照法):&amp;lt;/b&amp;gt; 提取特征帧, 状态张量补零&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;3.2 (流式模拟):&amp;lt;/b&amp;gt; 使用 `onnxruntime` 模拟流式推理, 捕获真实的非零状态张量&amp;lt;/div&amp;gt;&amp;#34;]:::task
 C --&amp;gt; R2{&amp;#34;&amp;lt;div style=&amp;#39;text-align:center&amp;#39;&amp;gt;INT8 模型推理结果?&amp;lt;/div&amp;gt;&amp;#34;}:::check

 R2 -- &amp;#34;3.1 -&amp;gt; Garbled Output&amp;#34; --&amp;gt; C
 R2 -- &amp;#34;3.2 (`interval=1`) -&amp;gt; &amp;lt;b&amp;gt;First Success&amp;lt;/b&amp;gt;&amp;#34; --&amp;gt; D

 D[&amp;#34;&amp;lt;div style=&amp;#39;text-align:left; padding:10px;&amp;#39;&amp;gt;&amp;lt;b&amp;gt;4. 量化策略调优&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;- &amp;lt;b&amp;gt;算法:&amp;lt;/b&amp;gt; 测试 `normal` (默认) 与 `kl_divergence` 算法&amp;lt;br&amp;gt;- &amp;lt;b&amp;gt;混合精度:&amp;lt;/b&amp;gt; 尝试手动及自动混合量化&amp;lt;/div&amp;gt;&amp;#34;]:::task
 D --&amp;gt; E

 E[&amp;#34;&amp;lt;div style=&amp;#39;text-align:left; padding:10px;&amp;#39;&amp;gt;&amp;lt;b&amp;gt;5. 最终方案验证&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;- 对比不同策略下的模型精度与性能 (RTF)&amp;lt;/div&amp;gt;&amp;#34;]:::task
 E --&amp;gt; F[&amp;lt;b&amp;gt;完成: 产出可部署的 INT8 RKNN 模型&amp;lt;/b&amp;gt;]:::success

 subgraph &amp;#34;关键技术点&amp;#34;
 K1[静态图 vs. 动态图]:::note
 K2[有状态模型的校准]:::note
 K3[量化算法内存分析]:::note
 K4[混合精度量化]:::note
 end

 A --&amp;gt; K1
 C --&amp;gt; K2
 D --&amp;gt; K3 &amp;amp; K4&lt;/pre&gt;
&lt;h3 id="3-工程实施细节与关键问题记录-implementation--key-findings"&gt;&lt;strong&gt;3. 工程实施细节与关键问题记录 (Implementation &amp;amp; Key Findings)&lt;/strong&gt;&lt;/h3&gt;
&lt;h4 id="31-初始模型转换"&gt;&lt;strong&gt;3.1 初始模型转换&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;执行动作&lt;/strong&gt;: 尝试使用 &lt;code&gt;rknn-toolkit2&lt;/code&gt; 直接转换模型提供方发布的 &lt;code&gt;int8.onnx&lt;/code&gt; 模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;观察结果&lt;/strong&gt;: 转换失败。工具链报错，指出模型中包含 &lt;code&gt;DynamicQuantizeLinear&lt;/code&gt; 算子，该算子与 RKNN NPU 的静态图 (Static Graph) 计算模式不兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;采取措施&lt;/strong&gt;: 确定了必须使用 &lt;code&gt;FP32&lt;/code&gt; ONNX 模型作为输入源，并利用 &lt;code&gt;rknn-toolkit2&lt;/code&gt; 自身的静态量化 (Static Quantization) 功能进行转换。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="32-c-推理框架-sherpa-onnx-适配"&gt;&lt;strong&gt;3.2 C++ 推理框架 (sherpa-onnx) 适配&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;执行动作&lt;/strong&gt;: 在使用 &lt;code&gt;FP32&lt;/code&gt; 模型成功转换为 &lt;code&gt;INT8&lt;/code&gt; RKNN 模型后，在 &lt;code&gt;sherpa-onnx&lt;/code&gt; 中进行推理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;观察结果&lt;/strong&gt;: 运行时报错，提示 &lt;code&gt;Unsupported tensor type: 2, INT8&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;采取措施&lt;/strong&gt;:
&lt;ol&gt;
&lt;li&gt;修改了 &lt;code&gt;sherpa-onnx&lt;/code&gt; 的 RKNN 后端 C++ 源码，在模型输入、输出及状态 (states) 处理逻辑中，增加了对 &lt;code&gt;RKNN_TENSOR_INT8&lt;/code&gt; 数据类型的分支处理。&lt;/li&gt;
&lt;li&gt;在获取模型输出后，根据 &lt;code&gt;rknn_tensor_attr&lt;/code&gt; 中的 &lt;code&gt;scale&lt;/code&gt; 和 &lt;code&gt;zp&lt;/code&gt; (zero_point) 参数，实现了手动的反量化 (Dequantization) 步骤，将 &lt;code&gt;INT8&lt;/code&gt; 输出转换为后续解码逻辑所需的 &lt;code&gt;FP32&lt;/code&gt; 数据。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="33-量化校准数据集的迭代与优化"&gt;&lt;strong&gt;3.3 量化校准数据集的迭代与优化&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;此阶段是项目核心，通过多次迭代确定了有效的校准数据生成方案。&lt;/p&gt;</description></item></channel></rss>