> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 从 Ubuntu EVK 演示到使用 QLI 的客户自维护 Yocto 系统（第 7 部分，共 7 部分）

> 使用 QLI 资源从快速的 Ubuntu EVK 演示迁移到客户自维护的、基于 Yocto 的产品软件候选。

<hr style={{ border: "none", borderTop: "1px solid #eee", margin: "0 0 2rem" }} />

<div style={{ display: "flex", justifyContent: "flex-start", marginBottom: "2rem" }}>
  <a href="/zh/tutorials/porting-the-full-multimedia-application-not-just-the-model" style={{ color: "#31017D", fontWeight: 600, textDecoration: "none" }}>← 上一篇：第 6 部分</a>
</div>

Ubuntu 是通往"它能跑起来"的快速路径。Qualcomm Linux（QLI）是一个面向 Qualcomm 硬件的、基于 Yocto 的嵌入式 Linux 发行版。它的参考发行版、元数据 layer、recipe 和示例代码可以帮助客户构建和维护自己的设备软件。

这一区分很重要。Ubuntu 给开发者一条通往 SSH、`apt`、`pip`、Python 脚本、AI Hub 下载、LiteRT 测试、GenieX 以及在 Dragonwing EVK 上快速迭代的短路径。选择基于 Yocto 系统的团队则承担另一种工作：

```text theme={null}
相同模型
相同应用行为
相同验证关口
更受控的 OS/BSP/运行时/更新故事
```

本文描述了从标准 Ubuntu 到使用 QLI 的基于 Yocto 系统的一种可能过渡。它**不**把 QLI 呈现为唯一的生产路径、成品的客户产品镜像，或 Qualcomm 代客户运营和维护的软件。Qualcomm 维护平台的部分内容，包括 Qualcomm 特定的内核和硬件启用工作，但客户仍负责选择、适配、集成、验证、保护、更新和维护其最终产品软件。

本文不替代 Qualcomm Linux 设置文档。请使用官方 Dragonwing Linux 页面来处理烧录、开发板设置、软件更新和设备特定的细节：

* [Qualcomm Linux 概览](/zh/qualcomm-linux-qli)
* [IQ-9075 EVK 设备概览](/zh/Linux/devices/iq9075-evk/device-overview)
* [IQ-8275 EVK 设备概览](/zh/Linux/devices/iq8275-evk/device-overview)

这里的迁移问题更窄：在 Ubuntu EVK 演示工作之后，当迁移到使用 QLI 资源构建的客户自维护基于 Yocto 的系统时，必须重新验证什么？在贯穿的案例研究中，这是第 6 部分那个智能摄像头包从 EVK 演示改编为版本化客户镜像的过程。

在开始之前：

```text theme={null}
[ ] Ubuntu EVK 演示通过功能验证
[ ] 模型/应用包已版本化
[ ] 已选择客户的 OS 策略：保留 Ubuntu、使用 QLI 资源或其他受支持路径
[ ] 已审阅 QLI/参考组件及其许可证/版本
[ ] 客户拥有的 Yocto layer、镜像和构建已版本化
[ ] 已记录 QAIRT/QNN、GenieX、LiteRT 和插件版本
[ ] 已记录目标 SoC/HTP 架构
[ ] 已定义持续延迟/FPS/功耗/热控关口
[ ] 已识别更新和回滚路径
```

***

## 两个里程碑

一次 Qualcomm 迁移有两个不同的成功里程碑。

```text theme={null}
里程碑 1：它在 Dragonwing EVK 上运行
  - 常常在 Ubuntu 上最容易
  - 快速的开发者迭代
  - 已知良好的 AI Hub / LiteRT / QNN / GenieX 测试
  - 模型和应用行为已证明

里程碑 2：客户拥有一个可维护的产品软件候选
  - 一个客户拥有的 Yocto/QLI 构建和 BSP 对齐
  - 锁定的运行时包
  - 服务管理
  - 功耗、热控、更新和安全计划
  - 补丁、合规和现场维护的记录所有权
```

常见的错误是把里程碑 1 当成里程碑 2。演示证明可行性；一个客户自维护的软件候选需要可重复的构建、验证、安全流程和明确的维护所有者。QLI 参考代码不会把这些责任转移给 Qualcomm。

***

## 为什么 Ubuntu 在早期有用

Ubuntu 是一个强大的第 0 天和开发环境，因为它为开发者速度优化：

```text theme={null}
熟悉的 shell
大型包生态系统
快速的 Python 迭代
简单的 `pip` / `apt` 工作流
容器友好的工具
快速的 AI Hub 和 GenieX 实验
```

当悬而未决的问题是这些时，那正是你想要的：

```text theme={null}
模型能干净地导出吗？
运行时能加载工件吗？
HTP 加速工作吗？
应用还能产生正确的输出吗？
我们在什么延迟和功耗的量级？
```

对于原型、实验室演示、内部工具和评估，Ubuntu 可能是暂时留下来的正确位置。

***

## 客户为什么可能选择 QLI 资源

QLI 是一个面向 Qualcomm 硬件的、基于 Yocto 的嵌入式 Linux 发行版。Dragonwing 文档描述了一个经过策划的技术栈，并为诸如 AI、GPU、DSP、摄像头和多媒体等领域提供参考发行版、layer、recipe、设置指导和硬件启用。文档称 QLI 面向生产；那描述的是它的设计目标，而不是产品所有权或维护责任从客户到 Qualcomm 的转移。

那可以帮助客户组装一个产品软件候选：

| 需求     | QLI 为什么有帮助                                  |
| ------ | ------------------------------------------- |
| BSP 对齐 | OS、内核、驱动、固件和用户空间一起构建                        |
| 更小的表面  | 产品镜像可以携带更少的开发包                              |
| 长期控制   | Yocto/OpenEmbedded layer 和 recipe 适合嵌入式产品维护 |
| 硬件集成   | 摄像头、多媒体、AI、GPU、DSP 和固件路径被协调                 |
| 制造     | 镜像创建、烧录、配给和恢复可以标准化                          |
| 更新     | 产品更新和回滚策略可以围绕 OS 镜像设计                       |

重点不是 Ubuntu "不对"，QLI 也不是一个强制目的地。客户可以留在 Ubuntu 上、使用 QLI 构建，或选择适合其硬件和产品的另一种 OS 策略。决策取决于客户的需求、维护模型、安全流程、合规义务和支持安排。

***

## 迁移前应证明什么

太早迁移会让每个问题看起来都像 OS 问题。太晚迁移会让原型假设渗入产品。

一个好的过渡点是当这些在 EVK 上为真时：

```text theme={null}
[ ] 源模型已恢复或从 AI Hub 选择
[ ] 已完成迁移适配性检查：摄像头数量、分辨率/FPS、内存、模型大小、编解码/显示、功耗、OS 约束
[ ] ONNX/源基线已验证
[ ] 已选择 Qualcomm 运行时路径
[ ] 已知良好的工件在预期处的 HTP/NPU 上运行
[ ] 预处理和后处理是显式的
[ ] 应用级指标在样本数据上通过
[ ] 延迟/FPS/功耗量级可接受
[ ] 部署包形态已知
```

到那时，迁移问题从"这能运行吗？"变为"这能在产品软件上反复运行吗？"

***

## 迁移期间会变什么

应用不应有太大变化。围绕它的环境会变化。

| 领域     | Ubuntu EVK 演示    | 客户自维护的 Yocto/QLI 候选     |
| ------ | ---------------- | ----------------------- |
| 包安装    | `apt`、`pip`、手动下载 | 镜像 recipe、锁定包、受控文件系统    |
| 运行时工件  | 测试期间手动复制         | 版本化包或镜像组件               |
| 服务启动   | shell 脚本或终端      | 受监督的服务                  |
| 日志     | 终端输出             | 带轮换/导出的持久日志             |
| 摄像头/媒体 | 演示流水线            | 产品摄像头/显示/编码路径           |
| 更新     | 重新烧录或手动复制        | 计划的 OTA/更新/回滚路径         |
| 安全     | 开发便利             | 最小权限、受锁访问、在适用处签名/可复现的工件 |
| 验证     | 冒烟测试             | 持续且可重复的关口               |

最安全的方式是让应用契约保持稳定，同时让 OS 变化。

***

## 重新验证运行时包和工件

AI 运行时工件绑定的不仅仅是模型。记录准确的矩阵：

```text theme={null}
SoC
HTP 架构
OS 镜像
BSP 版本
QAIRT/QNN SDK 版本
运行时库版本
如使用，GenieX 版本
如使用，AI Hub 作业/模型版本
模型精度
GenAI 的上下文长度
```

在下列任一变化时重建或至少重新验证：

```text theme={null}
Ubuntu -> QLI
BSP 更新
QAIRT/QNN SDK 更新
目标 SoC 变化
模型检查点变化
精度变化
后端变化
GenieX 运行时变化
```

对于 QNN/QAIRT 上下文二进制文件，假设目标敏感。更安全的做法是为客户所选的 OS/BSP/运行时组合重新生成和验证，而不是花两天调试一个陈旧的二进制。客户拥有这个重建和验证流程。

***

## 把演示变成一个包

在 Ubuntu 上，演示可能位于 home 目录中：

```text theme={null}
~/models
~/scripts
~/venv
~/demo.sh
```

对于 QLI，让运行时包显式化：

```text theme={null}
/opt/edge-ai-app/
  bin/
    app
    healthcheck
  models/
    detector.bin
    llm_bundle/
  config/
    pipeline.json
    preprocessing.json
    postprocessing.json
    thresholds.json
  labels/
    classes.json
  lib/
    应用特定的共享库
  manifest.json
```

示例清单字段：

```json theme={null}
{
  "app_version": "0.3.0",
  "target_soc": "QCS9075",
  "os": "Qualcomm Linux",
  "model_source": "best.pt sha256:...",
  "onnx_export": "model.onnx sha256:...",
  "runtime": "QNN/HTP",
  "precision": "a8w8",
  "qairt_sdk": "2.x",
  "ai_hub_job": "optional-job-id",
  "validation_set": "validation-v4",
  "expected_metric": "mAP >= 0.92"
}
```

那个清单是有意无聊的。当出现现场问题时，无聊就是极好的。

***

## 让它成为一项服务

一条终端命令对第 0 天是可以的。产品需要一个进程模型。

一份最小服务契约：

```text theme={null}
开机启动
如需要则等待摄像头/网络/模型存储
在实际可行时作为非 root 用户运行
崩溃时重启
写有用的日志
暴露一个健康检查
在模型/运行时版本不匹配时大声失败
```

一个小的 `systemd` 形态可能是这样：

```ini theme={null}
[Unit]
Description=Edge AI application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/edge-ai-app
EnvironmentFile=/opt/edge-ai-app/config/app.env
ExecStart=/opt/edge-ai-app/bin/app --config /opt/edge-ai-app/config/pipeline.json
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target
```

保持服务包装器薄。应用应拥有健康和清晰的错误消息；监督者应拥有重启策略。

***

## 在基于 QLI 的镜像上重新运行第 0 天检查

从第 2 部分继续沿用同样的健全性检查：

```text theme={null}
[ ] 设备可访问
[ ] 运行的是预期的 OS 镜像
[ ] QNN 工具可见
[ ] 可用时 HTP 验证通过
[ ] AI Hub/LiteRT/QNN 已知良好的模型运行
[ ] 如果 LLM/VLM serving 是产品的一部分，GenieX 路径运行
[ ] 自定义模型工件运行
[ ] 应用级指标通过
```

这避免了一个常见陷阱：在新 OS 镜像上证明基础运行时之前就调试自定义应用。

***

## 持续验证胜过峰值数字

产品验证应包括无聊的运行，而不仅是激动人心的基准测试。

运行应用足够长时间以捕捉：

```text theme={null}
热节流
内存增长
文件描述符泄漏
摄像头断开
网络掉线
时钟漂移
日志刷屏
看门狗循环
更新失败
```

建议的关口：

| 关口  | 示例                    |
| --- | --------------------- |
| 功能  | 在固定测试集上相同的输出          |
| 准确率 | 与 Ubuntu 基线相同的产品指标    |
| 延迟  | 真实摄像头负载下的 p50/p95/p99 |
| 吞吐量 | 持续的 FPS 或 tokens/sec  |
| 内存  | 长时间运行下稳定的 RSS         |
| 功耗  | 真实工作负载下的平均和峰值         |
| 热控  | 在运行长度内没有不可接受的节流       |
| 恢复  | 应用从摄像头/网络/模型服务重启中恢复   |

峰值 FPS 有用。持续行为才是可交付的。

***

## 及早规划更新和回滚

如果产品包含 AI，我们建议及早规划更新。模型会变。阈值会变。运行时包会变。安全修复会发生。

定义什么可以独立更新：

```text theme={null}
OS 镜像
AI 运行时包
模型工件
应用二进制文件
配置
标签/tokenizer/资源
```

然后定义回滚触发器：

```text theme={null}
服务启动失败
健康检查失败
模型/运行时清单不匹配
延迟或内存关口失败
摄像头流水线失败
用户或车队级金丝雀失败
```

只要客户拥有并运营构建、安全和更新流程，客户自维护的 Yocto/QLI 系统就可以为这种产品更新故事提供比松散开发镜像更受控的基础。

安全和更新细节不需要在首个产品候选中很详尽，但它们应该是显式的。诸如《欧盟网络弹性法案》之类的法规可以对包含数字元素的产品施加生命周期、漏洞处理和更新义务。客户的法务和安全团队必须确定哪些要求适用，并确保产品组织——而不是未修改的参考发行版——被指派为满足这些要求负责。

```text theme={null}
[ ] 已记录镜像来源和签名态势
[ ] 已理解安全启动 / 启动链要求
[ ] 设备身份和 API 秘密保持在应用包之外
[ ] 模型/配置回滚使用与应用回滚相同的健康关口
[ ] 已移除或控制调试 SSH、默认密码和开发包
[ ] 日志保留足够的证据而不泄露敏感输入
```

***

## 客户自维护系统检查表

在演示成为产品候选之前：

```text theme={null}
[ ] 已选择客户的 OS 策略：保留 Ubuntu、使用 QLI 资源或其他受支持路径
[ ] 已审阅 QLI/参考组件及其许可证/版本
[ ] 客户拥有的 Yocto layer、镜像和构建已版本化
[ ] 烧录/配给路径已从官方 Dragonwing 文档记录
[ ] QNN/QAIRT 运行时版本已锁定
[ ] 目标 SoC 和 HTP 架构已确认
[ ] 模型工件已为目标 OS/BSP 重建或重新验证
[ ] 如使用，GenieX 版本已锁定
[ ] 已创建部署包清单
[ ] 应用作为受监督的服务运行
[ ] 日志和健康检查可用
[ ] 摄像头/媒体路径在产品硬件上已验证
[ ] 在持续工作负载下已测量延迟/FPS/功耗
[ ] 热行为已验证
[ ] 已定义更新和回滚路径
[ ] 已记录制造/支持说明
```

***

## 智能摄像头案例研究的迁移账本

通过记录每个 Jetson 部件在 Dragonwing 上变成了什么来结束迁移：

| Jetson 部件                 | Dragonwing 部件                         |
| ------------------------- | ------------------------------------- |
| `best.engine` TensorRT 工件 | QNN/QAIRT 上下文二进制文件，如 `best_ctx.bin`   |
| TensorRT INT8 校准缓存        | Qualcomm 校准集加 QNN/AIMET 量化流程          |
| CUDA 预处理                  | IM SDK / `qtimlvconverter` / 共享预处理契约  |
| DeepStream `nvinfer`      | 带 QNN 委托的 `qtimlqnn` 或 `qtimltflite`  |
| DeepStream 元数据            | IM SDK 元数据加 `qtimetamux`              |
| CUDA 或 DeepStream 叠加      | `qtivoverlay` / 显示或编码路径               |
| 本地 LLM sidecar            | 当应用使用与 OpenAI 兼容的 API 时的 GenieX 本地服务器 |
| JetPack 镜像或容器             | 客户自维护的 Yocto/QLI 镜像加版本化运行时包           |

测量状态应该是显式的。如果实验室运行尚未完成，就直说，而不是暗示结果：

| 指标         | Jetson 基线 | Dragonwing 结果 | 状态      |
| ---------- | --------- | ------------- | ------- |
| 准确率 / 产品指标 | TBD       | TBD           | 等待实验室运行 |
| 延迟 / FPS   | TBD       | TBD           | 等待实验室运行 |
| 功耗 / 热控    | TBD       | TBD           | 等待实验室运行 |
| 持续运行长度     | TBD       | TBD           | 等待实验室运行 |

***

## 结论

Ubuntu EVK 演示是一个有用的首个里程碑。它在不预定客户最终 OS 策略的情况下，快速证明模型、运行时和应用形态。

如果客户选择 QLI，其发行版、layer、recipe 和参考材料可以支持这一过渡，但它们不会自动把演示变成产品。客户的工程组织必须把那些输入变成一个受控的产品候选：版本化的 OS、锁定的运行时、可复现的包、服务管理、持续验证和更新故事。

保持应用契约稳定、重建或重新验证目标敏感的工件，并让每个版本都可见。最重要的是，为 OS 维护、漏洞响应、更新、回滚和适用的监管/合规工作分配所有权。那才是从"它能跑"到客户自维护产品候选的路径。
