一键导入
msmodeling-device-config
在需要根据自然语言规格为未支持硬件新增或更新 DeviceProfile 设备画像条目时使用
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
在需要根据自然语言规格为未支持硬件新增或更新 DeviceProfile 设备画像条目时使用
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
当用户需要部署 msmodeling optix 服务化自动寻优工具时使用。负责安装与验证。
当首次使用 msmodeling optix 的用户需要根据硬件、模型、负载和优化目标推荐 MindIE/vLLM 寻优参数、搜索范围、benchmark 侧字段或 config.toml 片段时使用。
指导并自动化完成昇腾 NPU 上 MindSpeed-LLM 训练的 Profiling 数据采集。支持配置并运行带 Profiling 的模型训练,包括 CPU 采集、内存采集、不同采集级别(level0/level1/level2)和自定义 step 范围。生成的 Profiling 数据可用 MindStudio Insight 进行性能分析。当用户需要在模型训练中采集 Profiling 数据、进行训练性能分析、或执行 性能数据采集/Profiling采集 时触发。触发关键词:profiling、性能分析、性能数据采集、Profiling采集、训练框架profiling、MindSpeed-LLM profiling。
指导并自动化完成昇腾 NPU 上 MindSpeed-MM 模型训练的 Profiling 数据采集。通过识别训练脚本,自动找到配置文件并启用内置 Profiler,支持静态采集(指定起止 step)和动态采集(运行时动态开关),支持 Megatron 引擎(tools.json)和独立 FSDP2 引擎(YAML)两种配置方式。生成的 Profiling 数据可用 MindStudio Insight 进行性能分析。当用户需要在多模态模型训练中采集 Profiling 数据、进行训练性能分析、或执行 性能数据采集/Profiling采集 时触发。触发关键词:profiling、性能分析、性能数据采集、Profiling采集、多模态训练profiling、MindSpeed-MM profiling。
Skill for analyzing communication performance bottlenecks and detecting slow/fast rank issues in Ascend NPU systems. Use this skill whenever you need to analyze communication efficiency, data transfer bottlenecks, or identify slow/fast rank problems using profiling data.
用于分析Ascend NPU系统中计算性能瓶颈的技能,专注于算子效率和计算优化
| name | msmodeling-device-config |
| description | 在需要根据自然语言规格为未支持硬件新增或更新 DeviceProfile 设备画像条目时使用 |
| version | 0.4.0 |
| source | local-session-analysis |
引导用户把自然语言硬件描述转换为可运行、可校准、可复现的 DeviceProfile 设备画像。
ATLAS_800_A3_752T_128G_DIE 的 profile,并想添加相似条目。采用两阶段导入:
needs calibration,如果用户希望提高准确性,再继续收集校准数据。每轮对话都维护一张内部事实表:
confirmed:用户明确提供或确认的事实。ambiguous:单位、粒度、范围或指标含义不明确的事实。missing:写出可运行 profile 仍缺少的必要事实。needs calibration:为先跑通而暂用的默认值、估值、假设或省略项。默认写入目标:tensor_cast/device.py。生成的 DeviceProfile 应直接添加到该文件中,作为可被 --device <PROFILE_NAME> 直接引用的内置 profile。
不要默认新建 tensor_cast/device_profiles/<device_slug>.py。只有当用户明确要求临时 profile、自定义 profile 文件或隔离实验时,才写入 tensor_cast/device_profiles/。
编辑前先阅读 tensor_cast/device.py,确认现有厂商类、profile 命名风格、互联常量和 DeviceProfile 注册方式。只有在用户明确要求写入 tensor_cast/device_profiles/ 时,才需要额外阅读 tensor_cast/device_profiles/README.md 和 tensor_cast/device_profiles/__init__.py。
重要类型:
DeviceProfile(name, vendor, comm_grid, mma_ops, gp_ops, compute_efficiency, memory_size_bytes, memory_bandwidth_bytes_ps, memory_efficiency, static_cost)CommGrid(grid=torch.arange(...).reshape(...), topologies={start_dim: InterconnectTopology(...)})InterconnectTopology(bandwidth_bytes_ps, latency_s, comm_efficiency, type=InterconnectType.CLOS/FULL_MESH)StaticCost(mma_op_cost_s, gp_op_cost_s, comm_op_cost_s)DeviceProfile.__post_init__ 会把每个 profile 注册到 DeviceProfile.all_device_profiles,因此 name 必须唯一。默认把新增 profile 写入 tensor_cast/device.py;虽然 tensor_cast/device_profiles/__init__.py 会自动导入该目录下的每个 .py 文件,但这只作为用户明确要求自定义文件时的备用路径。
CommGrid.topologies 的 key 是 start_dim,不是随意的层级编号。通常 0 表示覆盖整个 grid 的最慢互联层,1 表示从第 1 维开始的更快子拓扑,最后一个维度表示最快的内层互联。当前实现要求 grid.ndim == len(topologies),并且每个 grid 维度至少为 2。
默认使用“新手引导模式”,除非用户主动一次性给出完整规格或要求高级模式。
mma_ops、gp_ops、CommGrid 等内部字段名;等用户理解对应含义后,再说明它们会写入哪个字段。tensor_cast/device.py 的估值、假设和插入位置。needs calibration 和可执行命令行示例。不要把“看起来合理”的硬件常识直接写成事实。只要不是用户明确给出的值或项目已有代码中的确定值,就必须标为待校准。
首轮提示应像下面这样,不要直接抛出完整参数表:
我们先不用填复杂参数,我会一步步问。
第一步只需要你告诉我三件事:
1. 这是什么硬件?比如厂商、型号或截图里的名称。
2. 你手头有什么资料?比如官网规格、截图、表格、口头描述。
3. 你希望先按“单卡”建 profile,还是硬件里有多个 die/chiplet 需要拆开?如果不确定,直接说“不确定”。
你可以直接粘贴原始描述或截图里的文字,我会帮你翻译成设备画像需要的字段。
后续按阶段推进:
mma_ops。gp_ops,优先找官方 vector/general 指标;没有时提供“留空”或“临时估值”选项。CommGrid。needs calibration。如果用户表现出不熟悉硬件术语,应优先给例子,而不是增加术语密度。
向新手解释时使用这些说法:
DeviceProfile:一张“硬件能力卡片”,记录某种硬件的算力、显存、带宽和互联。mma_ops:矩阵/张量计算峰值,主要影响矩阵乘、Linear、Attention 这类大算子。资料里常写成 FP16/BF16 TFLOPS、TOPS、Tensor Core、AI Core 算力。gp_ops:通用/vector 计算峰值,主要影响 softmax、norm、激活函数、逐元素计算等非矩阵算子。很多资料不会单独给,缺失时可以先留空或用待校准估值。needs calibration:为了先跑通而暂时使用的默认值、估值或不确定项,后续需要用实测或官方资料校准。以下是助手内部检查清单,不要原样丢给用户填写。对新手应拆成多轮问题,并配合上面的术语解释:
profile_name:稳定的大写名称,例如 ATLAS_800_A3_752T_128G_DIE。vendor:硬件厂商。sku:硬件型号或规格名,用于生成清晰的 profile 名称。granularity:该 profile 代表单卡、单 die、单 chiplet,还是其他调度单元。source_scope:用户给出的显存、带宽和算力是每个 profile 单元、整卡、整机、整节点还是整集群的值。memory_size:每个 profile 单元的 HBM/设备内存容量。memory_bandwidth:每个 profile 单元的内存带宽。mma_ops:按 dtype 区分的 tensor/matrix 峰值吞吐。gp_ops:按 dtype 区分的 general/vector 峰值吞吐。comm_grid:拓扑形状,以及每一层互联的带宽、延迟、效率和类型。如果缺少某项事实,提出有针对性的追问。如果用户无法提供,则只能在用户接受后使用兜底默认值或估值,并标记为 needs calibration。
首轮目标是降低门槛,不是收齐参数。如果用户使用中文,则用中文询问:
我们先不用填复杂参数,我会一步步带你配。
你先给我任意一种信息即可:硬件型号、官网规格截图里的文字、表格、或你知道的口头描述。
为了开始,我只问 3 个小问题:
1. 这是什么硬件?例如厂商和型号。
2. 你想先按一整张卡建 profile,还是这张卡里有多个 die/chiplet 需要拆开?不知道也没关系。
3. 资料里有没有写“显存容量”“显存带宽”或“FP16/BF16/INT8 算力”?有的话原样贴出来即可。
然后解析用户提供的信息,只追问缺失或存在歧义的必要事实。后续追问要解释为什么需要该信息,以及用户可以如何回答。
写文件前必须优先确认:
mma_ops 与 gp_ops 是否来自不同官方指标;不得默认二者相同。InterconnectType.FULL_MESH 还是 InterconnectType.CLOS。如果用户只想快速跑通,优先追问会导致代码错误或数量级错误的问题;其余问题可以进入 needs calibration。
显式规范化单位:
T、TFLOPS、TOPS -> * 1e12P、PFLOPS、POPS -> * 1e15GB/s 十进制带宽 -> * 1e9TB/s 十进制带宽 -> * 1e12GiB -> * (1024**3)TiB -> * (1024**4)needs calibrationus / microsecond 延迟 -> * 1e-6ns / nanosecond 延迟 -> * 1e-9映射 dtype 名称:
FP32、float32 -> torch.float32FP16、half、float16 -> torch.halfBF16、bfloat16 -> torch.bfloat16INT8 -> torch.int8FP8 -> DTYPE_FP8FP4、MXFP4 -> 仅当用户确认这对应当前 FP4 建模路径时,映射为 DTYPE_FP4不要编造 dtype 吞吐。如果某种关系看起来合理,应请用户确认,例如:INT8 峰值是否等于 FP16 的 2 倍?
如果用户给出的是“训练/推理峰值”“稀疏/稠密峰值”“Boost/Typical 峰值”或带条件的峰值,保留条件描述,并确认写入 profile 的值应该使用哪一个。
mma_ops 和 gp_ops 输入引导mma_ops 和 gp_ops 直接让用户填字段很容易卡住。改为以下流程:
直接问用户:“你的资料里有没有写 FP16/BF16/INT8 这类算力?直接贴过来就行,我来帮你对应到设备画像字段。”
支持的关键词映射(用户不需要知道这些术语):
| 用户资料里可能的写法 | 对应设备画像字段 |
|---|---|
| FP16 TFLOPS、FP16 算力、Tensor Core 算力 | mma_ops[torch.half] |
| BF16 TFLOPS、BF16 算力、AI Core 算力 | mma_ops[torch.bfloat16] |
| INT8 TOPS、INT8 算力 | mma_ops[torch.int8] |
| FP32 矩阵/张量 TFLOPS | mma_ops[torch.float32] |
| FP8 算力、MXFP8 | mma_ops[DTYPE_FP8] |
用户只需贴文字,例如:BF16 500 TFLOPS、FP16 800T,不必写成 Python 字典格式。
gp_ops(通用算力)如果资料里只有 mma_ops 相关的峰值,问用户:“资料里有没有单独给 vector/通用计算的峰值?比如 FP32 向量算力。很多硬件不会单独列这一项。”
如果用户有:按官方值填写 gp_ops,例如 FP32 向量算力对应 gp_ops[torch.float32]。
如果用户没有,提供以下选项,不要让用户空着不知所措:
gp_ops={} — 影响 softmax、norm、激活等逐元素算子的估算准确性,适合只想跑通整体流程的场景。mma_ops 的某个比例估算,例如 gp_ops[BF16] ≈ mma_ops[BF16] / 10。必须明确标注 needs calibration,并说明这是临时假设。gp_ops 会导致哪些算子无法被正确估算,建议后续补充。如果用户只给了 BF16 峰值,问:INT8 峰值是否等于 BF16 的 2 倍?FP8 是否等于 BF16 的 2 倍?
如果用户无法确认,分别用“待确认”和“待确认(2x BF16)”标注,列入 needs calibration。
将用户提供的峰值归一化后,用以下格式写入代码(不要暴露给用户看内部格式):
mma_ops={
torch.float32: <FP32 TFLOPS> * 1e12,
torch.bfloat16: <BF16 TFLOPS> * 1e12,
torch.half: <FP16 TFLOPS> * 1e12,
torch.int8: <INT8 TOPS> * 1e12,
DTYPE_FP8: <FP8 TOPS> * 1e12,
}
gp_ops={
torch.float32: <FP32 向量 TFLOPS> * 1e12,
torch.bfloat16: <BF16 向量 TFLOPS> * 1e12,
torch.half: <FP16 向量 TFLOPS> * 1e12,
}
仅当用户无法提供校准值且接受先跑通时使用:
compute_efficiency=0.7memory_efficiency=0.6comm_efficiency=0.7StaticCost(mma_op_cost_s=5 * 1e-6, gp_op_cost_s=2 * 1e-6, comm_op_cost_s=10 * 1e-6)所有兜底值都必须在最终回复的 needs calibration 下列出。
不要对以下核心硬件事实静默使用兜底:granularity、source_scope、每 profile 单元的显存、每 profile 单元的内存带宽、已写入 dtype 的吞吐、互联带宽方向。缺失这些事实时,应追问或明确得到用户同意后才使用估值。
当用户描述“整卡包含多个 die/chiplet”或提供的是整卡总规格时,先追问:
不要静默地把整卡规格除以 die 数。只有用户确认“可以均分”或数据手册明确给出 per-die 规格时,才能写入 per-die profile。
先用硬件术语询问:
将其转换为 CommGrid,外层维度表示更慢的层级,内层维度表示更快的层级:
CommGrid(
grid=torch.arange(<total_units>).reshape(<slow>, <middle>, <fast>),
topologies={
0: InterconnectTopology(...),
1: InterconnectTopology(...),
2: InterconnectTopology(..., type=InterconnectType.FULL_MESH),
},
)
grid.ndim 必须等于 len(topologies),并且每个 grid 维度都至少为 2。不要为了满足该约束而凭空增加不存在的拓扑层;未知层级应暂不建模,或让用户确认一个用于模拟的最小拓扑。
对于没有真实多设备拓扑的单卡或单 die profile,询问用户希望模拟的最小拓扑。不要创建单元素 grid,因为 CommGrid 会拒绝小于 2 的维度。
在编辑 tensor_cast/device.py 前,确认:
profile_name 唯一,并且不会与 DeviceProfile.all_device_profiles 中已有名称冲突。tensor_cast/device_profiles/<device_slug>.py,除非用户明确要求。DTYPE_FP4 / DTYPE_FP8 只在实际用到时导入。CommGrid 的每个维度都至少为 2,且 topologies 数量与 grid.ndim 一致。--device 后面的值等于 DeviceProfile.name。将生成的 DeviceProfile 直接添加到 tensor_cast/device.py 中现有厂商类的末尾(例如 ATLAS_800 类内),或在文件末尾新建小类来容纳。
# 放在 tensor_cast/device.py 中现有类末尾,或文件末尾新建类
class <CUSTOM_CLASS_NAME>:
_STATIC_COST = StaticCost(...)
_INTERCONNECT = CommGrid(...)
<PROFILE_NAME> = DeviceProfile(
name="<PROFILE_NAME>",
vendor="<VENDOR>",
mma_ops={...},
gp_ops={...},
memory_size_bytes=<...>,
memory_bandwidth_bytes_ps=<...>,
compute_efficiency=<...>,
memory_efficiency=<...>,
comm_grid=_INTERCONNECT,
static_cost=_STATIC_COST,
)
插入时注意:
profile_name 已在 DeviceProfile.all_device_profiles 中注册为唯一,不要覆盖已有名称。ATLAS_800)下添加,注意类已有的 _STATIC_COST 和互联常量是否可复用。<VENDOR>_<SKU>。DTYPE_FP4 或 DTYPE_FP8。运行导入/注册检查,确认 tensor_cast/device.py 中新增的 profile 已在模块导入时注册:
python - <<'PY'
from tensor_cast.device import DeviceProfile
print(DeviceProfile.all_device_profiles["<PROFILE_NAME>"])
PY
如果本地环境使用特定 Python 可执行文件,则遵循项目惯例。
验证后还要生成一条可执行命令,确保命令中的 --device 值就是新注册的 DeviceProfile.name:
python -m cli.inference.text_generate Qwen/Qwen3-32B --num-queries 2 --query-length 3500 --device <PROFILE_NAME>
如果导入失败,先修复 tensor_cast/device.py 中新增 profile 的问题;不要通过跳过注册或修改全局注册逻辑来掩盖问题。
最终必须给出一条可直接复制执行的命令。不要保留 TEST_DEVICE、TESE_DEVICE 或 <PROFILE_NAME> 这类占位符;必须替换成真实的 DeviceProfile.name。
默认命令模板:
python -m cli.inference.text_generate Qwen/Qwen3-32B --num-queries 2 --query-length 3500 --device <PROFILE_NAME>
生成时遵循:
--device 后必须是刚注册成功的 profile 名称,例如 --device FOO_X200_800T_96G。用户输入:
我们有个 Foo X200 单卡,显存 96GB,带宽 3.2TB/s。BF16 是 800T,FP16 是 800T,INT8 是 1600T,FP32 是 100T。8 卡机器,卡间 400GB/s。
期望的新手引导流程:
第一轮(助手): 先复述已理解的信息,并提出下一批问题:
好的,我理解了:
- 厂商/型号:Foo X200,粒度先按单卡。
- 显存:96GB,带宽 3.2TB/s。
接下来还需要几件事:
1. 【profile 名称】你想给这张卡起什么名字?例如 FOO_X200_800T_96G。我先按这个生成。
2. 【算力确认】资料里 BF16、FP16、INT8、FP32 的峰值都给了,很完整。你的资料里有没有单独给 vector(通用计算)算力?很多硬件不会单独列这一项。
- 如果有,直接告诉我数字。
- 如果没有,可以选:
a) 先留空,后续我来校准。
b) 先用 BF16 的 1/10 作为临时估值(我会标成待校准)。
3. 【卡间互联】8 卡之间 400GB/s 是单向还是双向?互联方式是全互联还是 CLOS?不知道的话可以直接说“我不确定,用默认的就行”。
第二轮(用户): 用户只回复第 2 和第 3 项:BF16 没有单独的 vector 算力,用留空吧。带宽我不确定单向还是双向。
第三轮(助手): 展示将写入 tensor_cast/device.py 的 profile、插入位置和 needs calibration,让用户确认后再写入;写入并验证成功后输出带真实 --device FOO_X200_800T_96G 的命令行。
用户输入:
我们有一个 Foo X200 单卡,感觉可以先按单卡建 profile。显存 96GB,带宽 3.2TB/s。BF16/FP16 是 800T,FP32 是 100T,INT8 是 1600T。8 卡机器,卡间 400GB/s,延迟先按 0.3us。节点间还不确定。
期望的助手行为:
Foo X200,粒度可能是单卡,内存为 96 GiB,内存带宽为 3.2 TB/s,mma_ops 包含 FP32/BF16/FP16/INT8,以及一个 8 卡拓扑候选。profile_name 是否使用 FOO_X200_800T_96G?vendor 是否写成 FOO?gp_ops 是否有官方 vector/general compute 峰值?如果没有,是否先用 FP32 10T、BF16/FP16 20T 作为待校准估值?gp_ops,不要静默编造。可以在用户接受的情况下只保留已知 dtype,或使用清晰说明的临时值。CommGrid 可以先建模已支持的范围。用户输入:
Bar Z9 一张卡 2 个 die,总算力 BF16 1200T,显存 192GB,卡内互联 900GB/s。我们调度时看起来像两个设备。
期望的助手行为:
BAR_Z9_600T_96G_DIE 的 per-die profile。needs calibration。用户输入:
只有截图:Baz NPU,FP16 500T,64G 显存。互联和 gp_ops 都没有,先让我能跑模型估算。
期望的助手行为:
gp_ops、内存带宽和互联拓扑缺失会影响估算准确性。needs calibration。简洁报告:
tensor_cast/device.py)和插入位置。DeviceProfile.name,如果验证失败则不要声称已注册。needs calibration:所有兜底值、假设、遗漏 dtype、近似带宽/延迟或单位歧义。--device 参数,最终回复必须使用真实名称,例如:python -m cli.inference.text_generate Qwen/Qwen3-32B --num-queries 2 --query-length 3500 --device FOO_X200_800T_96G
如果项目还有其他常用命令(如 tensor_cast 内省、tensor_cast simulate 等),也可以一并给出。
DeviceProfile.all_device_profiles 中是否已有重复名称。CommGrid 约束而凭空创造拓扑层级或设备数量。tensor_cast/device_profiles/ 文件;本 skill 默认追加到 tensor_cast/device.py。DeviceProfile.all_device_profiles 包含新的 profile 名称。