yolo11s-pose:架构与量化方案拆解

与 yolo11n-pose 拓扑完全相同、每层通道翻倍。网球的姿态打分头 tennis_pose_score_v0(3072 维特征)架在 s 上, 但同一条 tennis-latest v2.3 管线里的击球头 hitting_head_v0/coco 和持拍检测 racketeer_v3.0 都是 n,所以这条管线现在同时跑 n 和 s 两种骨干。这一页拆 s 的结构,逐项量出它和 n 在 量化上会有哪些不同,再把量化方案和对比实验列清楚。

n 和 s 用同一个脚本、同一口径实测:scripts/quant_y11s_profile.py, 权重是 ultralytics 官方 yolo11s-pose.pt(md5 e42e4d65…)与 yolo11n-pose.pt, BN 已折叠,输入 640×640,激活范围取自校准集 quant_calib_v1 的 128 张(letterbox 114)· 2026-09-23 · n 的完整讲解见 /v/y11pose/

总览

24 层,同样三段:backbone(0–10) → neck(11–22) → Pose 头(23)。 和 n 相比,差别只在宽度:层数、连线、C3k 开关、输出形状都一样。

从 n 到 s 改了什么

ultralytics 用同一份 yolo11-pose.yaml 缩放出 n/s/m/l/x。n→s 只改了 width 这一个旋钮。

项ns影响
depth / width / max_channels0.50 / 0.25 / 10240.50 / 0.50 / 1024只有宽度翻倍,深度(Bottleneck 重复数)不变
各层通道16 → 25632 → 512处处 ×2,卷积参数和 FLOPs 约 ×4
C2PSA 注意力头数24head_dim 64、key_dim 32、scale 0.1768 不变,头数随通道翻倍
Pose 头 cv2(框 DFL)中间宽度6464max(16, ch/4, 64) 被 16×4 的下限钉住,不随宽度变
Pose 头 cv3(类别)中间宽度64128max(ch[0], nc),跟着 P3 通道翻倍
Pose 头 cv4(关键点)中间宽度5151max(ch/4, 51),被 17×3 的下限钉住
输出(1,56,8400)(1,56,8400)完全相同:anchor 数、通道布局、DFL 16 bin 都一样
我们的抽头特征(层 4/6/8/10 avg+max)15363072现有板球打分/门控头不能直接用,要在 s 特征上重训
一个直接后果:Pose 头的宽度有两条分支被下限钉住,所以 s 的头只长了 , 远低于 backbone 的 。算力占比因此从头部移回 backbone(n 的头吃 37.7% FLOPs,s 只有 )。

结构图

与 n 同构。虚线是跨层连接(6→12、4→15、13→18、10→21);上方虚线是打分/门控用的抽头。

抽头:avg + max 池化 → 3072 维 256+256 · 256+256 · 512+512 · 512+512 BACKBONE 0–10 NECK 11–22 POSE 头 23 Pose(P3,P4,P5) → (1, 56, 8400) cv2 框 DFL 64ch · cv3 类别 1ch · cv4 关键点 51ch P3 128ch 80² · P4 256ch 40² · P5 512ch 20²
窄屏可左右拖动。方框里是层号、模块、输出通道与 stride(640 输入)。

三段各是什么

段结构产出(s)参数 svs n

每个模块内部怎么工作(C3k2 的 CSP 劈分、SPPF 串联池化、C2PSA、DFL)与 n 完全一样, 这里不重复,见 /v/y11pose/ 特殊层与特殊算子。下面只列 s 上数值变了的部分。

特殊算子:s 上的实际参数

C2PSA(layer 10)

注意力在 20×20=400 个 token 上做,QKT 是 4 个 400×400 的矩阵。 头多了一倍,但每个头的缩放不变,所以单个 logit 的量级主要由特征本身决定。

SPPF(layer 9)

1×1 卷积 512→256,三次串联 5×5 maxpool,四路 concat(1024 通道),再 1×1 回到 512。 maxpool 不产生新值,四路 concat 的幅度天然一致(实测比 1.01×)。

DFL(Pose 头内)

仍是 16 bin、权重 0…15 的 1×1 卷积。它的输出是像素坐标,与模型大小无关 —— 这决定了 s 的全模型臂和 n 一样必须 a16(见量化视角)。

代价分布:s 的钱花在 backbone

n 的 FLOPs 有 37.7% 在 Pose 头;s 的头只长了 1.8×,比例掉到约 21%,backbone 升到过半。 所以 s 从「只切 backbone」拿到的加速比 n 小。

backbone 0–10 neck 11–22 Pose 头 23
看数据表
模型段参数占比GFLOPs占比

逐层表

蓝色高亮行是抽头层。最后一列是这一层 s/n 的 FLOPs 倍数:卷积层都是 4×, Pose 头只有 1.7×,Upsample/Concat 是纯访存(2×)。

#模块from输出(s)参数 sGFLOPs sGFLOPs ns/n

GPU 实测:bs=1 看不出差别

A100 fp32,三个切点都带 8 路抽头。bs=1 下 n 和 s 几乎一样快,因为 GPU 此时受 kernel launch 限制,不受算力限制; bs=32 按每张摊下来,s 是 n 的约 1.9 倍。两种口径都不能直接换算到 HTP,端侧必须实测。