VGGT 推理 YAML 配置全解析:从单卡基线到多卡序列并行与 W8A8 量化
2026/9/18 14:31:50 网站建设 项目流程

VGGT 推理 YAML 配置全解析:从单卡基线到多卡序列并行与 W8A8 量化

【免费下载链接】cann-recipes-embodied-ai本项目针对具身智能业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-embodied-ai

本篇技术指南以cann-recipes-embodied-ai仓库中 VGGT 模型在昇腾 NPU 上的推理适配为例,系统讲解其 YAML 配置文件体系。你将掌握config/*.yaml中每个参数的含义、默认值与约束关系,理解计算冗余消除、多卡序列并行、INT8 量化与内存数据格式四大优化类别的底层实现原理,并能够独立完成从单卡基线推理到 2/4/8 卡并行推理、再到 INT8 量化模型构建与推理的完整配置与启动流程。

一、配置体系总览

VGGT 的推理参数全部通过config/*.yaml文件管理,启动入口demo_infer.py使用--config参数指定配置文件(默认值为config/single.yaml)。这一机制由 demo_infer.py 中的parse_args()实现:读取 YAML 后,分别提取model_argsworld_size,再经load_optimization_config解析optimization段,最终通过build_vggt_config组装为完整的推理配置对象(对应 utils.py 中的VGGTConfig数据结构)。

仓库预置了 5 套默认配置,覆盖单卡、多卡与量化三类典型场景:

配置文件场景world_size序列并行量化
single.yaml单卡基线1关闭bf16
sp2.yaml2 卡序列并行2开启(Ulysses=2, Ring=1)bf16
sp4.yaml4 卡序列并行4开启(Ulysses=2, Ring=2)bf16
sp8.yaml8 卡序列并行8开启(Ulysses=4, Ring=2)bf16
single_w8a8.yaml单卡 INT8 量化推理1关闭bf16 + W8A8

一个完整的配置文件由顶层元信息(model_nameworld_sizemaster_portentry_script)与两大配置段(model_argsoptimization)组成。下面以 single.yaml 为基准逐段拆解。

二、model_args:模型与推理运行参数

model_args段控制模型权重、输入数据与推理过程的基本行为:

model_args: ckpt: "ckpt/model.pt" # 模型权重路径(必填) images-path: "examples/kitchen/images" # 输入图片目录(必填) enable-profiling: false # 是否开启性能剖析 profile-dir: "prof_sp" # 剖析结果输出目录 num-runs: 6 # 推理运行次数

各参数要点:

  • ckpt:模型权重文件路径,必填。标准模型对应 README.md 中通过 Hugging Face 下载的model.pt;INT8 量化场景下则应指向生成的VGGT_model_W8A8.pt(见 single_w8a8.yaml)。
  • images-path:输入图片目录,支持相对路径或绝对路径。demo_infer.py中的_load_images_for_inference会递归收集目录下所有图片,经load_and_preprocess_images预处理后组成[1, N, 3, H, W]形状的批量张量。
  • enable-profiling / profile-dir:性能剖析开关与输出目录。开启后由 demo_infer.py 中的define_profiler创建 NPU+CPU 双活动剖析器,采用warmup=2, active=1的调度策略,多卡场景下结果按rank_{i}子目录分别落盘;关闭时使用空上下文管理器,零额外开销。
  • num-runs:正式推理的次数。单卡路径下_run_single_inference会先执行一次 warmup 再循环num_runs次;序列并行路径下_run_sp_inference_loop丢弃前 2 次结果(对应代码中step >= 2才记录日志),最终取剩余次数的平均值作为端到端推理耗时。

三、optimization:四大优化类别配置

optimization段是整个配置体系的核心,包含计算冗余消除、并行计算、量化、内存与数据格式四大类别:

optimization: # 计算冗余消除:通过缓存机制避免重复计算 computation-redundancy-elimination: rope-cache: true # 旋转编码缓存 dpt-pos-embed-cache: true # DPT 头位置编码缓存 cos-sin-dtype-optimization: true # Cos/Sin 数据类型优化 # 并行计算优化:利用多 NPU 并行,仅多卡场景生效 parallel-computation: enable: false # 并行计算总开关 ulysses-degree: 2 # Ulysses 序列并行度 ring-degree: 2 # Ring Attention 并行度 # 量化优化:降低数据精度以减少显存占用与计算开销 quantization: dtype: "bf16" # 模型数据类型:fp32 或 bf16 int8-w8a8: enable: false # INT8 量化开关 build: false # INT8 量化模型构建开关 # 内存与数据格式优化:提前转换数据格式,避免运行时转换开销 memory-and-data-format: conv-weight-layout-preconvert: true # 卷积核布局预转换

3.1 计算冗余消除(Computation Redundancy Elimination)

参数类型说明
rope-cachebool旋转编码三层缓存;关闭时每次重新计算
dpt-pos-embed-cacheboolDPT 头位置编码缓存;关闭时不缓存
cos-sin-dtype-optimizationboolCos/Sin 使用 bfloat16;关闭时使用 float64

rope-cache对应旋转编码的缓存机制,实现在 rope.py 的_compute_frequency_components中,代码注释明确其为"三层缓存":

  1. 基础频率缓存:以(dim, seq_len, device, dtype)为 key 缓存 cos/sin 频率分量表(frequency_cache);
  2. max 位置缓存:以(height, width)为 key 缓存input_positions.max() + 1的序列长度(源码中即max_position_cache思路);
  3. 2D 嵌入结果缓存:以(height, width, batch_size, seq_len)为 key 缓存垂直/水平方向 embedding 后的 cos/sin 张量(cos_sin_cache)。

旋转编码的输入依赖 positions 变量,而 positions 与输入图片的宽高相关,因此对同样大小的图片可完全复用结果,避免每次前向都重新生成 cos/sin 与求最大值。

dpt-pos-embed-cache对应 DPT 头的位置编码缓存,实现在 dpt_head.py。位置编码结果取决于输入图片大小与 token 长度,因此以(W, H, x.shape)为 key 缓存_compute_pos_embed的结果;关闭时回退到_apply_pos_embed_original每次重新计算。

cos-sin-dtype-optimization对应 Cos/Sin 算子输入数据类型优化。原生实现中 omega 变量使用torch.double(float64),导致算子下发到 AI CPU 执行、性能低下;优化后改为 bfloat16,使算子可调度到 NPU 矢量/AICore 上执行。该开关通过 demo_infer.py 中的set_cos_sin_dtype_optimization_enabled全局生效,其详细替换逻辑记录在 vggt_optimization.md。

3.2 并行计算(Parallel Computation,仅多卡生效)

参数类型说明
enablebool启用序列并行;单卡场景必须为 false
ulysses-degreeintUlysses 并行度,必须满足ulysses-degree × ring-degree = world_size
ring-degreeintRing 并行度,必须满足ulysses-degree × ring-degree = world_size

并行计算采用Ulysses + Ring Attention 混合序列并行方案:

  • Ulysses 并行:将num_heads(注意力头)维度切分到多卡,通过 all-to-all 通信实现 head 维度与序列维度的互换,使每个 rank 持有完整序列但只处理部分注意力头。约束num_attention_heads必须能被ulysses-degree整除。
  • Ring 并行:将序列维度切分到多卡,利用 NPU FIA 算子返回的 LSE(log-sum-exp)信息支持分块注意力结果的数值稳定合并,并采用通信与计算 overlap 策略隐藏通信开销。

两个并行度的关系约束在源码层被强校验:demo_infer.pysetup_sequence_parallel_groups(demo_infer.py)会显式检查world_size != ulysses_degree * ring_degree并抛出ValueError,同时按ring_degree组创建 Ulysses 进程组、按ulysses_degree组创建 Ring 进程组,最终构造SPConfig(ulysses_degree, ring_degree, use_ring_overlap=True)传入模型。

序列并行的具体算子适配见 unified_sp_attention.py(以npu_fused_infer_attention_score为底层实现)与 attention.py:Frame Attention处理帧内短序列,保持使用 PyTorch SDPA;Global Attention处理跨帧长序列,切换到 NPU FIA 融合算子,二者通过is_global_attention标志分流。

多卡推理要求输入图片数量足够多(序列足够长)才能体现并行收益,配置并行场景时应结合输入规模评估。

3.3 量化(Quantization)

参数类型说明
dtypestr模型数据类型:"fp32"(原始)或"bf16"(半精度)
int8-w8a8.enablebool启用 INT8 量化推理(W8A8)
int8-w8a8.buildbool构建 INT8 量化模型,仅首次运行时使用
  • dtype:模型整体数据精度。fp32为原始精度,bf16显存减半。demo_infer.py_load_model_with_spload_standard_model在加载权重后据此调用model.float()model.bfloat16()。仓库实测(见 vggt_optimization.md):bf16 相比 fp32 获得 6.62% 性能收益,相机位姿任务精度从 0.919 降至 0.911,损失在 0.5% 以内。
  • int8-w8a8.enable:INT8 量化推理开关。开启时模型加载走 W8A8 路径:激活使用动态 per-token 量化、权重使用静态 per-channel 量化。量化 Linear 层的实现见 vggt_linear.py:权重在__init__时通过torch_npu.npu_dynamic_quant离线量化为 int8 并保存 per-channel scale,前向时对激活做 per-token 量化,再经npu_quant_matmul以 bf16 精度输出。
  • int8-w8a8.build:量化模型构建开关。首次使用 INT8 时置为truedemo_infer.py会先加载标准模型,调用build_and_save_w8a8_model生成量化模型并保存到当前路径(文件名VGGT_model_W8A8.pt)后直接返回。

值得注意的量化范围:当前实现仅对 VGGT 模型中in_features == 4096的 Linear 层进行 8bit 量化,其余 Linear 层通过set_ignore_quantize标记跳过(见 vggt_utils.py)。仓库实测:fp32 模型约 4.9GB,bf16 约 2.46GB,int8 约 2.16GB;INT8 相比 bf16 相机位姿精度从 0.911 降至 0.907,损失在 0.5% 以内(vggt_optimization.md)。

3.4 内存与数据格式(Memory and Data Format)

参数类型说明
conv-weight-layout-preconvertbool卷积核预转换为 Fractal_Z 格式;关闭时使用默认格式

NPU 上进行二维卷积前需要先通过 Transdata 算子将卷积核转为Fractal_Z(NZ)私有格式,推理过程中存在格式转换开销。该优化在模型加载完成后调用cast_model_weight(实现见 cast_weight.py,调用逻辑见 demo_infer.py)递归遍历所有nn.Conv2d模块,提前执行torch_npu.npu_format_cast(weight.data, 4)(格式 4 即 Fractal_Z)完成转换,从而将转换开销从推理热路径中剔除。

代码中有一处平台相关的前提条件:is_ascend_950()返回 True 时跳过该转换(注释说明 950 仅支持 ND 格式,无需 NZ 转换),因此该优化实际作用于 Atlas A2/A3 等目标环境。

四、顶层元信息与参数约束

4.1 顶层字段

model_name: "vggt" # 模型名称 world_size: 1 # 启动进程数 master_port: 29600 # torchrun 主节点端口 entry_script: "demo_infer.py" # 入口脚本
  • model_name / entry_scriptyaml_parse.sh校验与解析时的必填字段;
  • world_size:进程数,即 NPU 卡数,多卡时必须等于ulysses-degree × ring-degree
  • master_porttorchrun启动时的分布式主节点端口,默认 29600。

配置文件校验逻辑见 yaml_parse.sh:vggt_validate_yaml会强制检查model_nameworld_sizeentry_script三个顶层键是否存在,并校验world_size为正整数,校验失败即中止启动。

4.2 量化参数关系

  • dtypeint8-w8a8.enable可以同时为 true(模型整体 BF16 + Linear 层 INT8),这也是 single_w8a8.yaml 采用的组合;
  • int8-w8a8.buildint8-w8a8.enable不应同时为 true(build 用于生成模型,enable 用于使用模型)。

4.3 并行计算参数约束

  • 必须满足ulysses-degree × ring-degree = world_size
  • 单卡场景(world_size=1)下,parallel-computation.enable必须为false
  • num_attention_heads必须能被ulysses-degree整除。

4.4 合法配置示例速查表

场景world_sizeparallel.enableulysses-degreering-degreedtypeint8-w8a8.enable
单卡推理1false11bf16false
单卡量化推理1false11bf16true
2 卡并行2true21bf16false
4 卡并行4true22bf16false
8 卡并行8true42bf16false

以上组合均与仓库预置配置文件一一对应,可直接套用。

五、多卡序列并行推理配置与启动

多卡推理通过 YAML 配置文件控制,关键参数如下:

参数说明
world_sizeNPU 卡数,必须等于ulysses-degree × ring-degree
optimization.parallel-computation.enable是否启用序列并行,多卡推理设为true
optimization.parallel-computation.ulysses-degreeUlysses 并行度,num_attention_heads必须能被其整除
optimization.parallel-computation.ring-degreeRing 并行度,约束ulysses-degree × ring-degree = world_size

以 8 卡为例,对应 sp8.yaml:

optimization: parallel-computation: enable: true ulysses-degree: 4 ring-degree: 2 model_name: "vggt" world_size: 8 master_port: 29600 entry_script: "demo_infer.py"

5.1 启动方式

方式一:Python 直接启动(仅单卡)

# 默认使用 single.yaml 配置(单卡推理) python demo_infer.py # 指定配置文件(单卡推理) python demo_infer.py --config config/single.yaml

demo_infer.pymain()(demo_infer.py)依据enable_sp或环境变量中是否存在RANK/WORLD_SIZE自动分流到序列并行路径或单卡路径。

方式二:Shell 脚本启动(支持单卡与多卡)

# 单卡推理(默认使用 single.yaml) bash infer_test.sh # 多卡推理(2 卡并行,内部调用 torchrun) bash infer_test.sh sp2.yaml # 多卡推理(4 卡并行) bash infer_test.sh sp4.yaml # 多卡推理(8 卡并行) bash infer_test.sh sp8.yaml

infer_test.sh的执行流程为:source CANN 环境变量 → 加载 yaml_parse.sh 与 vggt_launch.sh →vggt_parse_config解析配置并导出WORLD_SIZEMASTER_PORTENTRY_SCRIPT环境变量 →vggt_launch启动任务。

vggt_launch.sh的启动前会设置 NPU 优化环境变量与 HCCL 分布式通信配置:

# NPU 优化环境变量 export PYTORCH_NPU_ALLOC_CONF=${PYTORCH_NPU_ALLOC_CONF:-"expandable_segments:True"} export TASK_QUEUE_ENABLE=${TASK_QUEUE_ENABLE:-"2"} export CPU_AFFINITY_CONF=${CPU_AFFINITY_CONF:-"1"} export TOKENIZERS_PARALLELISM=${TOKENIZERS_PARALLELISM:-"false"} # HCCL 分布式通信配置 export HCCL_IF_IP=${LOCAL_HOST} export HCCL_IF_BASE_PORT=23456 export HCCL_CONNECT_TIMEOUT=1200 export HCCL_EXEC_TIMEOUT=1200

随后按world_size通过torchrun --master_port=${MASTER_PORT} --nproc_per_node=${WORLD_SIZE}(torchrun 不可用时回退到python -m torch.distributed.run)拉起分布式推理。run_inference_with_sp中通过dist.init_process_group(backend='hccl')初始化 HCCL 通信后端,每个进程绑定npu:{local_rank}设备。

5.2 多卡推理执行流程

序列并行推理的完整链路(对应 demo_infer.py):固定随机种子 → 初始化分布式 → 依据 YAML 创建 Ulysses/Ring 进程组 → 按dtype加载模型(可选conv-weight-layout-preconvert)→ 加载并预处理图片 → warmup → 开启剖析(可选)→ 循环num_runs次推理并统计耗时 → 输出平均推理时间。

六、INT8 量化推理完整流程

INT8 量化推理分为"构建"与"使用"两个阶段:

步骤 1:生成 int8 量化模型

修改配置,将 build 置为 true(enable 保持 false):

optimization: quantization: int8-w8a8: enable: false build: true

然后运行(yaml 文件名需替换为实际配置文件):

python demo_infer.py --config config/xxx.yaml

int8 模型会生成在当前路径(文件名:VGGT_model_W8A8.pt)。此阶段quick_start会走标准模型加载路径,调用build_and_save_w8a8_model完成量化模型构建与落盘后直接返回。

步骤 2:使用 int8 量化模型推理

使用 single_w8a8.yaml 配置文件(ckpt指向生成的量化权重、int8-w8a8.enable: true):

python demo_infer.py --config config/single_w8a8.yaml

七、性能剖析与结果输出

enable-profiling: true时,推理过程通过 NPU Profiler 采集算子级性能数据(AIC 流水线利用率等指标),结果保存到profile-dir指定目录;多卡场景下每个 rank 的结果独立存放于profile-dir/rank_{i}子目录。剖析器采用 Level1 级别的PipeUtilization指标采集,兼顾信息量采集与开销控制。

推理耗时统计方面:单卡路径逐次打印每次推理耗时并输出平均值;序列并行路径仅 rank 0 打印,且丢弃前 2 次(warmup 后数据)取均值。仓库在 8 卡 Atlas 800I A2 上的参考数据(见 vggt_optimization.md):25 张输入图片时,逐步叠加 Cos/Sin 优化、旋转编码优化、DPT 头优化、Add+LayerNorm 融合、BF16 权重、私有格式提前转换后,单卡推理耗时由 1324.83ms 降至 1121.09ms;序列并行下 Ulysses=2/4/8 分别获得 1.75x/3.43x/6.47x 提升,Ring=2/4/8 分别获得 1.82x/3.48x/6.42x 提升。上述性能数据与测试环境强相关,实际部署时请以自身硬件与输入规模实测为准。

八、使用注意事项汇总

  • 多卡配置必须满足world_size = ulysses-degree × ring-degree
  • 单卡场景(world_size=1)下parallel-computation.enable必须为false
  • 首次使用 INT8 量化时,需先设置int8-w8a8.build: true构建量化模型,之后改为enable: true使用;
  • buildenable不应同时为 true;
  • 性能剖析结果保存在profile-dir目录;
  • images-path支持相对路径或绝对路径;
  • 环境准备方面,本样例依赖 CANN 套件(当前为 CANN.8.5.0)、torch 2.7.1 与 torch_npu 2.7.1.post2,并需要从 VGGT 官方仓库以非覆盖模式复制网络结构代码(vggt/dependencyvggt/headsvggt/layersvggt/utils等目录),完整步骤见 README.md;
  • 使用一站式平台的用户可直接运行bash infer_platform_env_prepare.sh一键准备代码与权重,再以python demo_infer.py --config config/single.yaml完成单卡三维重建推理。

九、关联文档与进一步阅读

  • vggt_optimization.md:本篇配置中四大优化类别的详细原理、代码替换示例与性能数据出处;
  • vggt_accuracy_evaluation.md:VGGT 在相机位姿估计、点云重建、深度估计三个任务上的精度评测方法;
  • demo_infer.py:YAML 配置的消费方,完整展示了单卡/序列并行/量化三条推理路径;
  • config/:五套预置 YAML 配置,可直接作为自定义配置的模板;
  • vggt/layers/rope.py 与 vggt/heads/dpt_head.py:缓存类优化的底层实现。

【免费下载链接】cann-recipes-embodied-ai本项目针对具身智能业务中的典型模型、加速算法,提供基于CANN平台的优化样例项目地址: https://gitcode.com/cann/cann-recipes-embodied-ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询