feat/auc-recovery-plan #1
@@ -0,0 +1,102 @@
|
||||
# CTI 2026 推理优化 —— 冲击 80+ 设计文档
|
||||
|
||||
> 日期:2026-06-14
|
||||
> 赛题:百度商业 AI 技术创新大赛 — 生成式推荐广告排序推理性能优化
|
||||
> 当前最优:58.86(延迟 86.5s / AUC 0.7526 / PCOC 1.059)
|
||||
> 目标:榜上 ≥ 80
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心结论:80+ 必须靠 AUC,不能只靠延迟
|
||||
|
||||
队伍重构的评分公式已用两次真实提交验证,几乎完全吻合:
|
||||
|
||||
```
|
||||
score_latency = max(0, (300 - latency) / 300)
|
||||
score_model = ((AUC - 0.65) * 1000 + (0.15 - |PCOC - 1|) / 0.15 * 10) / 360
|
||||
score_all = score_latency * 70 + score_model * 30 # 仅当两项 > 0
|
||||
```
|
||||
|
||||
| 提交 | 延迟 | AUC | PCOC | 公式算分 | 实际 |
|
||||
|------|------|-----|------|----------|------|
|
||||
| 基线 | 229s | 0.759 | 1.110 | 25.87 | 25.85 ✓ |
|
||||
| 最优 | 86.5s | 0.7526 | 1.059 | 58.88 | 58.86 ✓ |
|
||||
|
||||
**硬推论:**
|
||||
|
||||
- `score_latency` 上限 = 70(仅当 latency → 0,物理不可能)。
|
||||
- 以模型自然 AUC ≈ 0.759、PCOC 完美计,`score_model` 上限 ≈ 9.9。
|
||||
- 故**绝对天花板 ≈ 79.9**;现实里延迟压到 ~10s 也只有 ~77。
|
||||
|
||||
因此 **80+ 必须有一部分来自比 0.7526 更高的 AUC**(在**验证集**上算)。榜上 80+ 的队伍一定是**又快、AUC 又更高**。当前队伍把全部精力投在延迟(58.86 中 49.8 来自延迟),而 30 分的模型桶几乎没动 —— 这正是通往 80+ 的缺口所在。
|
||||
|
||||
**前提需被证实/证伪**:上述天花板说明验证集上模型真实可达 AUC 必然明显高于 0.7526,即当前推理把 AUC 压低了;否则若验证集真实 AUC 也仅 ~0.76,则「80」这一目标本身需与队友及官方答疑再核对。**阶段 A 第一步(FP32 参考跑)就是用来验证这个前提的。**
|
||||
|
||||
## 2. 策略:方案 C —— 两条腿一起,AUC 优先
|
||||
|
||||
先做阶段 A(找回 / 最大化 AUC + PCOC 校准),再做阶段 B(结构性延迟重写),每一步都过本地测量关卡,确保不会用一次提交去赌一个回归。数学上**只有 A+B 一起**才能越过 80。
|
||||
|
||||
## 3. 约束与环境(来自官方规则)
|
||||
|
||||
- **硬约束(违一即 0 分)**:延迟 < 300s(只计 `model(batch)` 逐 batch 累加);AUC ∈ [0.65, 1.0];PCOC ∈ [0.85, 1.15];压缩包无 `dataset/`、无 `ckpt.pt`、文件在根目录、后缀为 `.zip/.tar.gz/.tar`;每天最多 10 次提交;`build_env.sh` ≤ 720s。
|
||||
- **允许**:量化(FP16/INT8)、Flash Attention(数学等价)、非结构化剪枝/稀疏(权重置零、形状不变)。
|
||||
- **禁止**:改层数 / 维度 / head 数 / FFN channel(结构化改动);序列采样或截断;对测试集训练。
|
||||
- **评测环境**:NVIDIA A800(80GB, SM80),Python 3.10 + PyTorch 2.6.0。评测数据集 ≠ 本地基线数据集(AUC 天然有差异)。最终人工审核合规性。
|
||||
- **实验环境**:AI Studio notebook + GPU,可加载 dataset 与 ckpt.pt,可本地自评 AUC/PCOC 后再提交。
|
||||
|
||||
## 4. 设计 · 第 1 节:测量闭环(地基)
|
||||
|
||||
在 notebook 里建一个带 instrumentation 的统一入口:
|
||||
|
||||
- **诚实计时**:`model(batch)` 前后加 `torch.cuda.synchronize()`。当前代码未同步、CUDA 异步,本地延迟数字不可信。
|
||||
- **配置开关板**:独立开关每个变换 —— `fp16 开/关`、`expert_merge 开/关`、`signid clamp/取模`、`特征截断 开/关`;一次运行打印 AUC / PCOC / 延迟 / 总分。
|
||||
- **锁定 FP32 参考跑**:先复现官方基线(FP32、不合并 expert、不截断),确立模型真实可达 AUC,作为天花板目标。
|
||||
|
||||
说明:本地测试集 AUC(~0.759)只是验证集 AUC(~0.7526)的代理,但改动**方向**可迁移 —— 本地是便宜信号,提交做最终确认。
|
||||
|
||||
## 5. 设计 · 第 2 节:阶段 A —— 找回 AUC(30 分桶)
|
||||
|
||||
按顺序做消融,每步过闭环;凡能提升(或不降低)AUC 的就保留:
|
||||
|
||||
1. **Sign-ID 处理(头号嫌疑)**:查 `max_sign_id` 与 5M 词表关系。`values.clamp(0, max_idx)` 把所有超界 ID 压到第 4,999,999 行;若训练用取模哈希,clamp 即与训练不一致、污染大量 embedding,可能是大幅 AUC 损失。对比 `clamp` vs `% vocab_size`。
|
||||
2. **精度摆放**:`Embedding`、最后 `linear` 头、`LayerNorm` 保留 FP32,仅大矩阵乘走 FP16;对比一刀切 `.half()` 找回多少 AUC。
|
||||
3. **Expert 合并代价**:测其真实 AUC delta;只换延迟,掉 AUC 即砍掉。
|
||||
4. **特征完整性**:核对 `max_feasign_per_slot={1:2}` 及任何 `max_ctx_len` 截断,确认没丢有信息量的特征/历史。
|
||||
5. **上下文完整性**:确认每条测试样本 attend 到该用户完整历史(因果 mask packing 正确、历史按 userid 正确挂上)。
|
||||
|
||||
**目标**:把有效 AUC 从 0.7526 拉向真实天花板。每 +0.01 AUC ≈ +0.83 分,且是唯一突破 ~78 的杠杆。
|
||||
|
||||
## 6. 设计 · 第 3 节:阶段 B —— 结构性延迟重写(86.5s → ~15–25s)
|
||||
|
||||
之前失败的是高层魔法(torch.compile、INT8)。真正的硬骨头是热点结构,按收益排序,**只碰计算顺序/内核,不碰数学结果**:
|
||||
|
||||
1. **注意力 mask(最大单点)**:当前每 batch 现造稠密 `S×S` bool mask 喂 SDPA,**稠密 attn_mask 会让 Flash/cuDNN 退回低效路径**(Flash 名义开、实际没生效)。序列按用户 packing,应改为**块对角 + 块内因果**(per-user block-diagonal causal),让 SDPA 走快路径。
|
||||
2. **MoE 向量化**:消掉每层 8-expert 的 Python 循环、每 expert 的 `.nonzero()` 与隐含 GPU 同步,改分组 GEMM / 批量 expert 计算。
|
||||
3. **Embedding 池化融合**:每 batch 串行 28 次 `segment_reduce` → 融合为更少 kernel;处理 slot 19 重复 sign(去重 × 计数,等价省带宽)与 slot 28 瓶颈。
|
||||
4. **加大 batch**:50 → 更大(盯显存),摊薄 2039 batch 的 launch 开销。
|
||||
5. **重估 torch.compile / CUDA Graph**:图理干净后再试;CUDA Graph 用「按序列长度分桶」绕开变长形状限制。
|
||||
|
||||
**目标**:~15–25s;每步仍用闭环验证 AUC 不变。
|
||||
|
||||
## 7. 设计 · 第 4 节:PCOC 校准(低优先、免费零头)
|
||||
|
||||
PCOC 当前 1.059 已在区间内。对预测做单调缩放/偏移(temperature/bias),**不改 AUC**(单调变换不影响排序),把 PCOC 推向 1.0,约 +0.33 分并降低踩红线风险。**校准只在带标签的历史数据上做,绝不碰测试集**。收益小,标记为可选,提交前确认合规。
|
||||
|
||||
## 8. 设计 · 第 5 节:合规与提交纪律
|
||||
|
||||
- **每个改动先分类**:改权重数值(量化/稀疏/剪枝 ✅)/ 改结构(❌)/ 用测试集训练(❌)。Sign-ID 处理与上下文组织必须与训练一致,否则不是「同一个模型」。
|
||||
- **提交预算**:10 次/天;先用本地闭环卡住,只提交本地确有提升的候选;维护提交日志。
|
||||
- **人工审核风险**:避开任何像「钻计时空子」的做法(如靠异步不同步虚报延迟)。
|
||||
- **保底**:永远留一个已知能跑、不为 0 的回退提交(当前 58.86 版本)。
|
||||
|
||||
## 9. 设计 · 第 6 节:成功标准
|
||||
|
||||
- **主目标**:榜上 ≥ 80。
|
||||
- **过程关卡**:(a) 本地复现 FP32 基线 AUC,确立真实天花板;(b) 找到 ≥1 个值 ≥0.01 AUC 的找回杠杆;(c) 延迟 ≤ 25s;(d) PCOC ∈ [0.95, 1.05]。
|
||||
- **硬约束全程不破**:AUC ≥ 0.65、PCOC ∈ [0.85, 1.15]、延迟 < 300s、压缩包规范。
|
||||
|
||||
## 10. 风险与未决项
|
||||
|
||||
- **核心前提待验证**:验证集真实可达 AUC 是否显著 > 0.7526。FP32 参考跑给出本地答案;首次「找回 AUC」候选的提交给出验证集答案。若证伪,需重新校准「80」目标并与队友/官方答疑核对。
|
||||
- **延迟与 AUC 的张力**:FP16、expert 合并等换延迟的手段可能掉 AUC;以 AUC 为先,延迟从不损精度的结构性重写中补。
|
||||
- **本地 ≠ 验证集**:本地分数仅作方向信号,最终以提交为准。
|
||||
Reference in New Issue
Block a user