Files
CTI-Inference-Opt/CLAUDE.md
T

15 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

项目概述

百度商业AI技术创新大赛 (CTI) 2026 — 生成式推荐广告排序推理性能优化

目标:给定 GRAB Transformer 模型,在不改模型结构、不在测试集训练的前提下,极致优化推理性能。量化/稀疏/剪枝明确允许。

环境与常用命令

# 激活虚拟环境
.\.venv\Scripts\Activate.ps1

# 本地运行推理(需要 dataset/ 和 ckpt.pt
.\.venv\Scripts\python.exe 代码\code\infer.py
.\.venv\Scripts\python.exe 代码\code\infer.py --ckpt path/to/ckpt.pt

# AI Studio SDK(下载数据集、提交)
.\.venv\Scripts\aistudio.exe download --dataset <id> --local_dir ./dataset --token <token>
.\.venv\Scripts\aistudio.exe download --model <id> --local_dir . --token <token>

# 打包提交
cd 代码/code && zip -r ../../submit.zip infer.py requirements.txt build_env.sh

本地环境仅装 numpy + tqdm + aistudio-sdk(轻量),完整 PyTorch 依赖见 代码/code/requirements.txt,训练/推理在服务端跑。

代码架构

infer.py  (单文件,~730 行,所有逻辑集中于此)
├── 数据加载层
│   ├── _detect_has_clk()          — 检测 CSV 是否有 clk 列
│   ├── load_sample_files()        — 加载 CSV → item_dict + user_seq
│   ├── load_logids_from_file()    — 快速提取文件中所有 logid
│   └── CTRUserDataset(Dataset)    — 按用户组织的 CTR 数据集
│       └── make_collate_fn()      — 将用户样本拼接为 batch(含 slot 特征展开)
├── 模型层
│   ├── RepEncoder                 — Slot-wise Embedding → LayerNorm → Linear
│   │   └── Embedding(5M vocab, 512d) × 28 slots → segment_reduce(sum) → concat
│   ├── TransformerEncoder (8 层)
│   │   ├── QKV Projection → Multi-Head Attention (scaled_dot_product)
│   │   ├── SMoE FFN8 experts, Top-2 gating, 每层独立)
│   │   └── Pre-LayerNorm + Residual
│   ├── CTRModel                   — RepEncoder + Transformer → Linear → logit
│   │   └── Causal mask: 同一用户的 tokens 因果遮罩,不同用户隔离
│   └── load_model(ckpt_path, device) — 模型构建 + 权重加载入口
├── 推理循环 (main)
│   ├── 数据加载(优先缓存 shard_*.pt)
│   ├── 逐 batch 推理 + 计时(只计 model(batch) 耗时)
│   └── 按 test.csv 顺序写 predict.txt
└── 打分工具
    └── _cal_score() — AUC + PCOC + latency → score_all

模型参数规模Embedding 5M×512 + 8 层 Transformer (d_model=512, n_heads=8, dim_ff=1024) × MoE(8 experts) ≈ 6.5M11.3M 参数。

关键接口(评测系统调用契约)

评测系统通过 from infer import ... 加载代码,以下是必须对齐的接口(来自 代码/任务提交接口说明.md):

接口 签名 说明
load_sample_files (sample_files_list: List[Path]) -> (item_dict, user_seq) 数据加载
CTRTestSeqDataset (test_logids_ordered, item_dict, user_seq, max_feasign_per_slot, max_ctx_len) 必须有 max_slot_id 属性
make_collate_fn (max_slot_id) -> Callable DataLoader 的 collate_fn
load_model (ckpt_path: Path) -> (model, device) 第一个参数是 Path
move_batch_to_device (batch, device) -> batch
model(batch) -> (logits, moe_loss) logits 经 sigmoid 后是点击概率

致命不匹配baseline infer.py 当前存在,提交前必须修复):

  1. 类名 CTRUserDataset → 应为 CTRTestSeqDataset
  2. 构造参数 pred_logids → 应为 test_logids_ordered,缺少 max_ctx_len
  3. load_model(device='cuda:0', ckpt_path=None) → 应为 load_model(ckpt_path, device='cuda:0')Path 作为第一参数)

提交规范

压缩包结构

submit.zip
├── infer.py              # 必需,实现上述全部接口
├── requirements.txt      # 可选,阿里云 PyPI 镜像安装
└── build_env.sh          # 可选,超时 720s,非 0 退出即失败

硬约束(任一违反 → 总分 0

  • 推理耗时 < 300s(只计 model(batch) 逐 batch 累加)
  • AUC ∈ [0.65, 1.0]PCOC ∈ [0.85, 1.15]
  • 压缩包内不能dataset/ckpt.pt
  • 包后缀只能是 .zip/.tar.gz/.tar,解压后文件在根目录
  • 每天最多提交 10 次

总分公式

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

评测环境

  • 硬件: NVIDIA A800 (80GB, SM80)
  • 软件: Python 3.10 + PyTorch 2.6.0
  • 评测数据集 ≠ baseline 数据集AUC 天然有差异)

优化合规边界(来自官方 Q&A)

操作 状态 说明
量化(FP16/INT8 允许
Flash Attention 允许 数学等价实现
参数级剪枝/稀疏化(权重置零/mask,形状不变) 允许 权重矩阵大小、层数、head 数、FFN 维度均不变
减少 Transformer 层数 违规 改变组网结构
减少 hidden 维度 违规 改变张量形状
删除 attention head 违规 改变组网结构
减少 FFN channel 违规 改变组网结构
序列采样/截断 违规
对测试集训练 违规

剪枝细则(来自 Q&A #3

  • 结构化剪枝( 不允许): 删除整层、整行/整列权重、减少 channel 数等,会改变张量形状或网络拓扑
  • 非结构化剪枝( 允许): 仅将单个权重置零或 mask 掉,不改变权重矩阵形状;可删除对输出贡献较小、冗余度高的部分,前提是结构不被破坏

关键边界:Linear 权重矩阵大小不变、Layer 数量不变、Attention head 数量不变、FFN 维度不变 → 属于合规的参数级剪枝

评测细节

  • 计时范围: 仅 model(batch) 逐 batch 累加,move_batch_to_device 不计入
  • 硬件: NVIDIA A800 (80GB, SM80)
  • 软件: Python 3.10 + PyTorch 2.6.0
  • 评测数据集 ≠ baseline 数据集AUC 天然有差异)
  • 策略指标以 baseline 为上限,指标下降会扣分,超出范围直接 0 分
  • 人工审核:最终成绩由人工审核判定合规性

数据分析

数据规模

维度 数值
历史数据 15 文件 × ~650K 行 = 923 万行15GB
测试集 7,774 条预测13MB
缓存 batch 9 个 shard17GB,共 2,039 batch
Slot 数量 1-2828 个特征槽)

数据格式

# History5 列,含 clk:
logid,userid,adid,clk,timestamp,sign:slot,...

# Test4 列,无 clk:
logid,userid,adid,timestamp,sign:slot,...

特征分布特征

  1. Slot 28 是瓶颈槽位:每个样本含 30-50 个 sign:28 特征,远超其他 slot。segment_reduce 在 slot 28 上占据 RepEncoder 最大开销。
  2. Slot 19 高度冗余:同一样本内连续出现大量相同 sign:19(如 96:19 重复 40+ 次)。在 segment_reduce(sum) 中,N 个相同 sign 等价于 N × emb,但代码独立查表 N 次再求和,浪费 embedding 带宽。
  3. 特征极度稀疏:百万级 sign id,每个样本仅 100-200 个 sign。Embedding 查表是主要内存瓶颈。

数据驱动的可优化方向

方向 合规性 预估收益 说明
Slot 19 同值合并 ⚠️ N 个相同 sign 合并为 N × emb,减少 embedding 查表次数。属数据预处理灰区
Slot 28 segment_reduce 融合 将 slot 28 的大量 sign 预先按 offset 分桶,减少 kernel launch
Embedding 查表带宽 已用 FP16embedding 5M×512 约 5GB

优化路线图(来自 推理优化方案.md

Baseline 数据:推理 229sAUC 0.759PCOC 1.110,得分 25.85。

  1. 接口对齐 — 确认能在评测系统跑通(得分 > 0)
  2. FP16 量化model.half()Embedding 保留 FP32152s
  3. Flash Attention — 替换 scaled_dot_productF.scaled_dot_product_attention94.5s
  4. inference_mode() — 替代 no_grad()92.5s+2s 小幅提升)
  5. SMoE 消除 GPU 同步 — 移除 mask.any()64 次 GPU→CPU 同步/forward),88.1s
  6. Expert 权重相似度合并 — 余弦相似度 >0.90 的 expert 合并(权重平均),86.5s
  7. 稠密向量化 MoE — einsum 并行算 8 个 expert + gather 选取,消除 nonzero 同步(PR #1
  8. RepEncoder 融合查表 — 28 slot 值拼成一条做单次 segment_reduce,减 per-batch kernel 启动(PR #1
  9. Searchsorted 因果 mask — 替代 repeat_interleave(张量repeats),消除最后同步点(PR #1)
  10. 过滤无关用户 — 跳过不含测试样本的用户,省算力(PR #1)
  11. torch.compile — 四种模式全验证,均反效果。CONFIG 默认 compile=false(注释:实测慢5×)
  12. MoE Top-1 gating — PCOC 炸毁
  13. 2:4 结构化稀疏 — 两次尝试均炸 PCOC
  14. INT8 量化 — CUDA 后端不支持
  15. varlen attention — 本地 10.3s 但评测端 148s(慢 65%),已回退
  16. FlexAttention — 比 SDPA 慢,未启用

已验证无效/失败:torch.compile(×4)、2:4 稀疏(×2)、MoE k=1(×2)、INT8、varlen attention、FlexAttention

关键文件

路径 用途
代码/code/infer.py 推理主脚本(提交的核心文件)
代码/code/requirements.txt 服务端依赖(torch 2.6.0 + CUDA 12.4
代码/code/build_env.sh 环境构建脚本(目前为空壳)
代码/任务提交接口说明.md 官方接口规范
推理优化方案.md 完整优化方案(含合规审查)
论文/GRAB.pdf GRAB 论文 OCR markdown
论文/HSTU.pdf HSTU 论文 OCR markdown
论文/GRAB_*.pdf GRAB 论文(baseline 模型)
论文/HSTU_*.pdf HSTU 论文(架构基础)
.gitignore 排除 ckpt.pt, dataset/, *.zip, .venv/

提交记录

团队成员用户名 score pcoc score_latency score_model latency auc 提交状态 提交时间 备注
刘航宇 异常 2026-06-12 20:46 requirements.txt 含 nvidia-* 包,无 Windows 轮子
刘航宇 异常 2026-06-12 21:24
刘航宇 43.55 1.0589 0.4931 0.3013 152.08s 0.7525 已完成 2026-06-12 21:30 首次 FP16 量化成功(仅 infer.py 提交)
刘航宇 异常 2026-06-12 21:40
刘航宇 56.98 1.0589 0.6849 0.3013 94.54s 0.7526 已完成 2026-06-12 21:44 SDPA 替换 scaled_dot_product
刘航宇 32.54 1.0587 0.3357 0.3013 199.28s 0.7525 已完成 2026-06-12 21:54 torch.compile 实验(反效果)
刘航宇 0 2.0749 0.6013 0 119.62s 0.7361 已完成 2026-06-12 22:12 2:4 结构化稀疏 → PCOC 炸毁
刘航宇 51.42 1.0587 0.6055 0.3013 118.35s 0.7525 已完成 2026-06-13 11:54 inference_mode() 替代 no_grad()
刘航宇 57.45 1.0589 0.6916 0.3013 92.53s 0.7526 已完成 2026-06-13 12:07 参数调优
刘航宇 0 2.0672 0.1150 0 265.51s 0.7484 已完成 2026-06-13 12:21 2:4 稀疏第二次 → PCOC 再次炸毁
刘航宇 57.04 1.0589 0.6858 0.3013 94.27s 0.7526 已完成 2026-06-13 12:41 回退稀疏,恢复调优
刘航宇 58.49 1.0589 0.7065 0.3013 88.06s 0.7526 已完成 2026-06-13 13:17 消除 MoE mask.any() GPU 同步
刘航宇 58.45 0.9889 0.7244 0.2579 82.67s 0.7336 已完成 2026-06-13 13:32 AUC 骤降 0.019PCOC 0.989 偏低),回退
刘航宇 异常 2026-06-13 13:55 build_env.sh CUDA warmup device='cuda' 失败
刘航宇 0 1.3450 0 0 307.44s 0.7506 已完成 2026-06-13 14:10 MoE k=1 → PCOC 炸毁
刘航宇 53.71 1.0589 0.6381 0.3013 108.57s 0.7524 已完成 2026-06-13 14:21 回退 k=2,恢复
刘航宇 55.10 1.0587 0.6580 0.3013 102.59s 0.7525 已完成 2026-06-13 14:38 compile 实验
刘航宇 58.47 1.0589 0.7062 0.3013 88.13s 0.7526 已完成 2026-06-13 14:46 关闭 compile,最优基线确认
刘航宇 55.19 1.0589 0.6594 0.3013 102.19s 0.7526 已完成 2026-06-14 11:18 Expert 相似度合并 th=0.97(阈值过高,几乎未合并)
刘航宇 58.86 1.0589 0.7117 0.3013 86.49s 0.7526 已完成 2026-06-14 11:32 Expert 合并 th=0.90,旧版最优分
刘航宇 58.52 1.0589 0.7068 0.3013 87.95s 0.7526 已完成 2026-06-14 11:46 微调 th=0.85
刘航宇 58.25 1.0589 0.7030 0.3013 89.11s 0.7526 已完成 2026-06-14 12:11 微调 th=0.80
刘航宇 58.38 1.0589 0.7049 0.3013 88.54s 0.7526 已完成 2026-06-14 12:25 旧版回退(PR#1 合并前基线)
qianban139 58.05 1.0589 0.7001 0.3013 89.96s 0.7526 已完成 2026-06-14 23:09 张君硕首次提交(PR#1 代码基线)
qianban139 44.40 1.0589 0.5052 0.3013 148.44s 0.7525 已完成 2026-06-15 09:19 varlen attention 实验 → 评测端慢 65%,回退
qianban139 62.81 1.0589 0.7682 0.3013 69.55s 0.7525 已完成 2026-06-15 09:43 回退 SDPA,恢复调优
qianban139 63.03 1.0589 0.7713 0.3013 68.60s 0.7525 已完成 2026-06-15 11:59 参数调优
qianban139 63.29 1.0589 0.7750 0.3013 67.49s 0.7525 已完成 2026-06-15 12:16 参数调优
qianban139 63.20 1.0589 0.7737 0.3013 67.88s 0.7525 已完成 2026-06-15 12:40 参数调优
qianban139 63.67 1.0589 0.7805 0.3013 65.86s 0.7525 已完成 2026-06-15 12:48 参数调优
qianban139 65.17 1.0589 0.8019 0.3013 59.44s 0.7524 已完成 2026-06-15 13:47 参数调优(AUC 微降 0.0001
qianban139 67.87 1.0589 0.8404 0.3013 47.88s 0.7524 已完成 2026-06-15 14:23 🔥 当前最高分!参数调优(AUC 微降 0.0002)
qianban139 67.21 1.0589 0.8311 0.3013 50.68s 0.7524 已完成 2026-06-15 15:37 继续调参,略有回退
刘航宇 62.95 1.0589 0.7702 0.3013 68.93s 0.7525 已完成 2026-06-15 17:19 PR#1 代码(稠密MoE+融合查表+syncfree mask

团队成员

AI Studio 用户名 真实姓名
qianban139 张君硕
sidny1988 谢松熹
(队长账号) 刘航宇