mcpField
J
jetson-customize-nvpmodel

jetson-customize-nvpmodel

github.com/nvidia开发3.8k1.1k 次安装今天更新
代码仓库

关于 jetson-customize-nvpmodel

用于 Jetson / Tegra 的技能,可在 BSP 覆盖副本中管理 nvpmodel 电源模式、频率限制和启动默认模式。它要求保留上游文件只读,并按板卡变体同步修改与验证配置。

主要功能

  1. 01新增、删除或编辑电源模式
  2. 02调整 CPU、GPU、EMC、TPC 限制
  3. 03更改启动默认模式
  4. 04列出已定义模式
  5. 05校验频率与配置引用

适用场景

  1. 01为 Jetson 添加自定义功耗配置
  2. 02修改默认启动电源模式
  3. 03检查当前 SKU 的模式和默认值

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nvidia/skills --skill jetson-customize-nvpmodel

安装后在 Claude Code 中输入/jetson-customize-nvpmodel确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

BENCHMARK.md
skill-card.md
skill.oms.sig
evals/
evals.json

详细介绍

修改 nvpmodel 电源模式(BSP 侧)

用途

编辑每块板的 nvpmodel 配置,使设备启动时使用所需的电源模式组、CPU/GPU/EMC/TPC 限制值以及默认模式。仅限 BSP 侧操作——所有写入都落在覆盖层跟踪目录中,上游的 bsp_image 副本为只读。

此技能用于编辑每块板的 nvpmodel 配置文件,包括添加模式、移除模式、编辑 CPU/GPU/EMC/TPC 限制值以及更改启动默认模式。适用于 Jetson / Tegra 平台(T234 Orin、T264 Thor)。

文件格式(以 BSP 文件头中的规范为准)

# 1. PARAM definitions — declare named knobs and their sysfs paths
< PARAM TYPE=FILE  NAME=<param_name> >
<arg_name> </absolute/sysfs/path>
...
< PARAM TYPE=CLOCK NAME=<param_name> >
FREQ_TABLE        </sysfs/.../available_frequencies>
MAX_FREQ          </sysfs/.../max_freq>
MIN_FREQ          </sysfs/.../min_freq>
FREQ_TABLE_KNEXT  </sysfs/.../available_frequencies>     # kernel-NEXT variant
MAX_FREQ_KNEXT    </sysfs/.../max_freq>
MIN_FREQ_KNEXT    </sysfs/.../min_freq>

# 2. POWER_MODEL definitions — one block per profile
< POWER_MODEL ID=<int> NAME=<string> >
PARAM_NAME ARG_NAME <value>
...

# 3. PM_CONFIG — mandatory; selects boot default
< PM_CONFIG DEFAULT=<id> >

规则:

  • 对于 TYPE=FILE,<value> 是字符串(0、1、on、auto 等)。
  • 对于 TYPE=CLOCK,<value> 是整数(时钟使用 Hz,掩码使用原始整数)。
  • CLOCK 值为 -1 表示 INT_MAX(不设上限)。
  • 文件头 < … > 行必须从第 0 列开始,且 < 和 > 前后各有一个空格。此规则严格执行。
  • POWER_MODEL 中引用的每个 PARAM_NAME 都必须已在上方声明。
  • 频率值必须来自该时钟在内核的 available_frequencies 表——不在表中的值会被静默舍入。
  • CORE_0 不能下线;每个配置中至少必须有一个 CPU 核心保持在线。
  • 从每块板文件中现有的 POWER_MODEL 块中逐字复制 PARAM 名称——不同芯片系列的命名不同(T234 Orin 的 CPU 集群使用 CPU_A78_<n>;T264 Thor 使用不同的命名约定)。不要自行编造。

前置条件

根据 ../../context/target-platform-contract.md 解析活动配置文件。遇到以下情况时拒绝操作并转交:

条件拒绝时转交至
没有活动配置文件,或 active: NA转交至 /jetson-set-target 或 /jetson-init-target。
配置文件缺少 bsp_image: 块转交至 /jetson-init-image。
<bsp_image.root_path>/Linux_for_Tegra/ 不存在转交至 /jetson-init-image。
<source.root_path>/Linux_for_Tegra/ 不存在或不是 git 仓库转交至 /jetson-init-source。

解析路径:

  • 如果存在 bsp_image.root_path:,则使用 <bsp_image.root_path>;否则使用 <workspace>/Image。
  • 如果存在 source.root_path:,则使用 <source.root_path>;否则使用 <workspace>/Source。

此技能对 <bsp_image.root_path> 只有只读权限;所有写入都落在 <source.root_path>(覆盖层跟踪目录)下。这是 ../../context/bsp-customization-workflow.md#workflow-invariants 中规定的工作流不变量——手动编辑上游文件会在不知不觉中破坏差异跟踪记录,并导致 /jetson-promote-image 变成空操作。

每块板的文件

此技能编辑的配置文件的相对路径为:

Linux_for_Tegra/rootfs/etc/nvpmodel/nvpmodel_<active-sku>.conf

该文件位于两个根目录中;此技能会同时检查两处:

角色位置技能是否写入?
检测 + 原始源文件<bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpmodel/否——只读
覆盖层编辑目标 + git 提交<source.root_path>/Linux_for_Tegra/rootfs/etc/nvpmodel/是

后续章节中的每块板的文件均指 <source.root_path> 下的覆盖层副本。操作 1–4 均读取、编辑并保存此覆盖层副本。<bsp_image.root_path> 副本只会在“解析 <active-sku>”检测步骤中读取一次,并在覆盖层编辑流程的原始文件导入步骤中读取一次,此后不再触碰。

解析 <active-sku> —— 要编辑哪个文件

文件名并不总是 module.id + "_" + module.sku。存在以下变体:

  • nvpmodel_p3767_0000_super.conf(super-mode SKU 变体)
  • nvpmodel_igx_orin.conf、nvpmodel_igx_orin_safety.conf(IGX,无 SKU 编号)

启动时,nvpower.sh(位于 Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh)会读取内核 DTB 的根 compatible 字符串,并结合 super/safety 状态,将其映射到 nvpmodel 文件名。在 BSP 侧对 <bsp_image.root_path> 执行同样的映射:

  1. 在 <bsp_image.root_path>/Linux_for_Tegra/ 下找到与 SKU 对应的内核 DTB,并读取其根 compatible(从当前使用的 flash conf 检测内核 DTB)。
  2. 读取 <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/systemd/nvpower.sh,找到 compatible 字符串到 conf 的映射,并将其应用于上一步得到的 compatible(同时考虑 super/safety 标志)。
  3. 确认解析出的 nvpmodel_<...>.conf 存在于 <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpmodel/ 下。

快捷方法:将 <bsp_image.root_path>/Linux_for_Tegra/rootfs/etc/nvpmodel/ 筛选为 nvpmodel_<module.id>_<module.sku>*.conf;对于 super-mode flash 配置,选择 _super 变体。仅在结果明确无歧义时使用;否则改用 DTB 方法。

不要盲目拼接 nvpmodel_<id>_<sku>.conf——请确认文件确实存在。

传播集 —— 需要保持同步的 conf

当前 SKU 文件通常不是唯一需要包含自定义更改的 conf。编辑后,将相同更改应用到传播集中的每个同级文件,确保无论启动时使用哪个模块 / 底板 SKU,更改都能生效:

  • 参考平台的 nvpmodel conf —— 当前文件派生自的上游 conf(通过当前配置文件中的 reference_devkit 或 jetson-derive-carrier 的派生关系确定)。对于仅包含参考平台(没有派生底板)的 BSP,该文件与当前文件相同,因此此规则不需要额外操作。
  • 每个由底板派生的 nvpmodel conf —— jetson-derive-carrier 为基于相同模块 SKU 的自定义底板生成的每个 nvpmodel_*.conf。
  • 存在时的 _super 同级文件(例如 nvpmodel_p3767_0000_super.conf)——应用结构性更改(新增 POWER_MODEL 块、移除块、切换 PM_CONFIG DEFAULT=、重命名 NAME),但保留 super conf 中更高的 MAX_FREQ / MIN_FREQ 上限。这些提高后的上限正是 _super 变体存在的原因;若直接用非 super 文件覆盖全部内容,会悄悄抹平 super 配置范围。

“应用相同更改” ≠ 整个文件直接复制。 将更改过的 POWER_MODEL / PARAM 行移植到每个同级文件中;保留其他所有行。只有在两个 conf 修改前逐字节完全相同时,才可以直接复制整个文件。否则,请按照每个目标文件的 Rules 重新验证(时钟值对应的 available-frequencies 表、ID 唯一性、PM_CONFIG DEFAULT= 引用的 ID 是否存在)——同级 conf 可能包含 SKU 专属的 available_frequencies 表,不一定接受当前文件中的频率值。

Overlay 编辑流程(在执行任何 Operation 前应用)

遵循工作流文档中的规范 Off-skill edits recipe——先导入原始文件,再提交自定义更改;两者都必须通过预览门槛。每次运行应用一次,涵盖本次运行涉及的每个板级文件(当前 conf 以及 传播集中的每个同级文件)。

本技能的具体替换内容:

  • <rel>/<file> 为 rootfs/etc/nvpmodel/<conf>。
  • 建议的原始文件导入提交信息: import pristine: <comma-separated rel paths of imported confs>, 正文为 Source: <bsp_image.root_path>/Linux_for_Tegra/ (BSP <bsp_image.version>)。
  • 建议的自定义提交标题: jetson-customize-nvpmodel: <summary>, 正文行示例:nvpmodel_p3767_0001.conf: PM_CONFIG DEFAULT 2 -> 0 (MAXN)。

说明

选择符合用户意图的操作,并按照对应的小节执行。所有写入操作(1–4)都必须先应用 Overlay 编辑流程。

  • 操作 1 — 添加新的电源模式(通过 NVIDIA Power Estimator 生成配置)。
  • 操作 2 — 移除电源模式。
  • 操作 3 — 编辑现有电源模式(限制值、核心在线状态、NAME)。
  • 操作 4 — 更改启动默认项(PM_CONFIG DEFAULT=)。
  • 操作 5 — 列出已定义的电源模式(只读)。

任何写入操作完成后,运行部署链(## Deploy),将更改应用到设备。

示例

从 Power Estimator 导出文件添加新的 30 W 电源模式,并将其设为 P3767-0001 目标的启动默认项:

/jetson-customize-nvpmodel
> add a new POWER_MODEL from ~/Downloads/nvpmodel_30W.conf as ID 8 NAME "30W_CUSTOM"
> set PM_CONFIG DEFAULT to 8

将启动默认项切换为 MAXN 电源范围,使 Thor 目标达到该范围(无需调整电源范围):

/jetson-customize-nvpmodel
> set PM_CONFIG DEFAULT to the MAXN profile's ID

列出当前 SKU 定义的电源模式,以及启动默认项:

/jetson-customize-nvpmodel
> list defined power modes

操作 1 — 添加新的电源模式

先应用 Overlay 编辑流程。

通过 Power Estimator 生成配置文件

不得通过对现有配置文件中的频率进行插值或外推来估算功耗。

对于任何非出厂默认的电源范围(自定义功耗预算、自定义工作负载),请使用 NVIDIA Power Estimator:https://jetson-tools.nvidia.com/powerestimator/

  • 选择准确的模块 SKU 和 JetPack 版本。
  • 输入工作负载(CPU 核心、GPU 使用率、EMC、编解码器、摄像头、显示器)。
  • 估算功耗预算。
  • 下载自定义的 nvpmodel.conf。
  • 分享下载的 nvpmodel.conf 文件路径。
附加 POWER_MODEL 块

在每块板对应的文件中,将新块插入最后一个 < PARAM … > 声明之后(POWER_MODEL 必须引用已声明的 PARAM),并放在最后一行 < PM_CONFIG ... > 之前。块的结构采用上文所示的文件格式;频率值取自 Power Estimator 的输出(参见“通过 Power Estimator 生成配置文件”)。

检查 ID 是否唯一;NAME 应为大写且不含空格。每个数值型 MAX_FREQ / MIN_FREQ 值都必须符合 available_frequencies 规则(参见规则)。如果要将此模式设为启动默认项,请遵循操作 4。

操作 2 — 移除电源模式

先应用 Overlay 编辑流程。

  1. 在每块板对应的文件中,删除整个 < POWER_MODEL ID=<n> NAME=... > 块,包括其中所有参数行,直到下一个 < POWER_MODEL ... > 或 < PM_CONFIG ... > 标记之前。
  2. 如果删除的 ID 与结尾 < PM_CONFIG … > 行中当前的 DEFAULT=<id> 值相同,请将 DEFAULT= 指向剩余的某个 ID;否则 nvpmodel 将无法在启动时应用默认项。
  3. 在确认此更改安全之前,搜索 rootfs 脚本中是否存在硬编码引用:
    grep -rn "nvpmodel -m" \
      Linux_for_Tegra/rootfs/etc \
      Linux_for_Tegra/rootfs/opt 2>/dev/null
    

ID 不连续是合法的 — 无需重新编号剩余模式。

操作 3 — 编辑现有电源模式

先应用 Overlay 编辑流程。

  1. 在每块板对应的文件中,编辑块内的参数行。保持 <param> 和 <arg> 名称与 PARAM 声明完全一致。
  2. 如果编辑会改变电源范围(任何 CPU/GPU/EMC/PVA/DLA 的 MAX_FREQ / MIN_FREQ、受频率限制模式的核心在线数量,或 TPC 掩码),请重新运行 NVIDIA Power Estimator(参见“通过 Power Estimator 生成配置文件”),以实际的各组件模型为新频率提供依据。不要根据相邻模式进行插值。
  3. 根据 available_frequencies 规则验证时钟值(参见规则)。

仅切换已验证电源范围内的核心在线标志,或仅更改 NAME= 的编辑,无需运行 Power Estimator。

操作 4 — 更改启动默认模式

请先应用叠加层编辑步骤。

编辑各板级文件底部的 < PM_CONFIG DEFAULT=<id> > 行。

<id> 必须引用同一文件中现有的 < POWER_MODEL ID=<id> … > 块。若指向未定义的 ID,nvpmodel 将无法在启动时应用设置。

操作 5 — 列出已定义的功耗模式

这是只读操作;无需设置叠加层跟踪器。针对要检查的副本运行 (原始状态使用 <bsp_image.root_path>/...,编辑后状态使用 <source.root_path>/...):

grep -E '^< POWER_MODEL ' <per-board file>
grep -E '^< PM_CONFIG '   <per-board file>

第一条命令会输出每个 ID/NAME;第二条命令会输出当前的启动默认模式。在运行中的目标设备上,nvpmodel -p --verbose(或 nvpmodel -q)提供权威信息。

限制

  • 仅限 BSP 侧操作 — 此技能绝不会在运行中的目标设备上调用 nvpmodel -m。要实时切换模式,必须通过 Deploy 重启,或使用 ## Deploy 中介绍的旁路 scp + nvpmodel -m 流程。
  • 编辑仅会写入 <source.root_path> 下的叠加层副本;<bsp_image.root_path> 副本为只读,并会由 /jetson-promote-image 重写。手动编辑 bsp_image 的内容会在下一次 /jetson-init-image 重新提取时静默丢失。
  • 频率值必须来自相关时钟的内核 available_frequencies 表 — 表外的值会被静默舍入。此技能不会对照运行中目标设备的频率表进行验证;请以各板级文件中的现有值和 Power Estimator 输出为准。
  • 非简单的功耗范围编辑(更改任何 CPU/GPU/EMC/PVA/DLA MAX_FREQ / MIN_FREQ)都需要使用 NVIDIA Power Estimator(https://jetson-tools.nvidia.com/powerestimator/)— 不支持对现有模式之间的值进行插值或外推。
  • 按设计,仅会部分传播到同系列型号:只移植更改过的 POWER_MODEL / PARAM 行,不会整文件覆盖,因为 _super 同系列型号带有必须保留的较高 MAX_FREQ/MIN_FREQ 上限。
  • PARAM 名称因芯片系列而异(例如,T234 使用 CPU_A78_<n>,T264 使用不同名称)。请从现有的 POWER_MODEL 块中原样复制;自行编造的名称会导致设置静默失效。

故障排除

错误原因解决方案
nvpmodel 在启动时无法应用默认模式PM_CONFIG DEFAULT=<id> 引用了已删除或缺失的 POWER_MODEL ID将 DEFAULT= 指向同一文件中现有的 < POWER_MODEL ID=<n> ... >。
频率值未生效且没有提示该值不在对应时钟的内核 available_frequencies 表中替换为运行中目标设备的 available_frequencies(或 Power Estimator 输出)中最接近的合法值。
MAX_FREQ -1 不起作用对 TYPE=FILE PARAM 使用了 -1(仅对 TYPE=CLOCK 有效)仅对 CLOCK 参数使用 -1;对于 FILE 参数,应写入 sysfs 节点要求的实际字符串。
模块失效/编辑后无法启动CORE_0 被下线,或模式低于平台的最低静态功耗范围保持 CORE_0 在线;根据该 SKU 的 Power Estimator 最低功耗配置设置 MIN_FREQ 下限。
nvpmodel -m <id> 运行时返回“ID not found”模式 ID 已被移除或重新编号,但某个 rootfs 脚本仍引用旧 ID运行 grep -rn 'nvpmodel -m' rootfs/etc rootfs/opt,并更新/删除过时的引用。
/jetson-init-image 重新提取后更改消失编辑落在 <bsp_image.root_path>,而不是 <source.root_path> 覆盖层中按照覆盖层编辑流程重新应用更改,使其记录在覆盖层跟踪器中。
传播后 _super 同级项失去了提升的上限全量文件复制覆盖了 _super 较高的 MAX_FREQ/MIN_FREQ仅移植结构性更改;按照传播集合保留 _super 的上限。
解析器拒绝新的 POWER_MODEL 块标头 < … > 未从第 0 列开始,< 后或 > 前缺少空格,或 PARAM 未提前声明恢复严格的标头格式;确保每个被引用的 PARAM_NAME 都已在上方的 < PARAM ... > 块中定义。

部署

覆盖层跟踪器中的自定义提交本身不会到达设备。部署流程如下:

  1. /jetson-promote-image — 将覆盖层中所有已跟踪的文件复制到 <bsp_image.root_path>/Linux_for_Tegra/。 根据差异决定是否复制(跳过字节完全相同的文件);对于 rootfs/* 目标,使用 sudo cp -p。
  2. /jetson-flash-image — 将更新后的 bsp_image 刷入设备。
  3. (替代方式,无需刷写)将 <source.root_path>/Linux_for_Tegra/rootfs/etc/nvpmodel/<conf> 直接复制到运行中目标设备的 /etc/nvpmodel/<conf>,然后运行 sudo nvpmodel -m <id>(或重启以应用新的 DEFAULT=)。

编辑 <source.root_path>/... 却不提交,或直接编辑 <bsp_image.root_path>/...,都不会影响 /jetson-promote-image 的结果,并且会在下次 /jetson-init-image 重新提取时悄然丢失。

评论

支持 Markdown