34671a2a29
Co-Authored-By: Claude <noreply@anthropic.com>
14 KiB
14 KiB
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 FFN(8 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 当前存在,提交前必须修复):
- 类名
CTRUserDataset→ 应为CTRTestSeqDataset - 构造参数
pred_logids→ 应为test_logids_ordered,缺少max_ctx_len 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 个 shard,17GB,共 2,039 batch |
| Slot 数量 | 1-28(28 个特征槽) |
数据格式
# History(5 列,含 clk):
logid,userid,adid,clk,timestamp,sign:slot,...
# Test(4 列,无 clk):
logid,userid,adid,timestamp,sign:slot,...
特征分布特征
- Slot 28 是瓶颈槽位:每个样本含 30-50 个
sign:28特征,远超其他 slot。segment_reduce在 slot 28 上占据 RepEncoder 最大开销。 - Slot 19 高度冗余:同一样本内连续出现大量相同
sign:19(如96:19重复 40+ 次)。在segment_reduce(sum)中,N 个相同 sign 等价于N × emb,但代码独立查表 N 次再求和,浪费 embedding 带宽。 - 特征极度稀疏:百万级 sign id,每个样本仅 100-200 个 sign。Embedding 查表是主要内存瓶颈。
数据驱动的可优化方向
| 方向 | 合规性 | 预估收益 | 说明 |
|---|---|---|---|
| Slot 19 同值合并 | ⚠️ | 小 | N 个相同 sign 合并为 N × emb,减少 embedding 查表次数。属数据预处理灰区 |
| Slot 28 segment_reduce 融合 | ✅ | 中 | 将 slot 28 的大量 sign 预先按 offset 分桶,减少 kernel launch |
| Embedding 查表带宽 | ✅ | 小 | 已用 FP16,embedding 5M×512 约 5GB |
优化路线图(来自 推理优化方案.md)
Baseline 数据:推理 229s,AUC 0.759,PCOC 1.110,得分 25.85。
- ✅ 接口对齐 — 确认能在评测系统跑通(得分 > 0)
- ✅ FP16 量化 —
model.half(),Embedding 保留 FP32,152s - ✅ Flash Attention — 替换
scaled_dot_product为F.scaled_dot_product_attention,94.5s - ✅ inference_mode() — 替代
no_grad(),92.5s(+2s 小幅提升) - ✅ SMoE 消除 GPU 同步 — 移除 mask.any()(64 次 GPU→CPU 同步/forward),88.1s
- ✅ Expert 权重相似度合并 — 余弦相似度 >0.90 的 expert 合并(权重平均),86.5s
- ✅ 稠密向量化 MoE — einsum 并行算 8 个 expert + gather 选取,消除 nonzero 同步(PR #1)
- ✅ RepEncoder 融合查表 — 28 slot 值拼成一条做单次 segment_reduce,减 per-batch kernel 启动(PR #1)
- ✅ Searchsorted 因果 mask — 替代 repeat_interleave(张量repeats),消除最后同步点(PR #1)
- ✅ 过滤无关用户 — 跳过不含测试样本的用户,省算力(PR #1)
- ❌ torch.compile — 四种模式全验证,均反效果。CONFIG 默认 compile=false(注释:实测慢5×)
- ❌ MoE Top-1 gating — PCOC 炸毁
- ❌ 2:4 结构化稀疏 — 两次尝试均炸 PCOC
- ❌ INT8 量化 — CUDA 后端不支持
- ❌ varlen attention — 本地 10.3s 但评测端 148s(慢 65%),已回退
- ❌ 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 |
| 刘航宇 | — | — | — | — | — | — | 异常 | 2026-06-12 21:24 |
| 刘航宇 | 43.55 | 1.0589 | 0.4931 | 0.3013 | 152.08s | 0.7525 | 已完成 | 2026-06-12 21:30 |
| 刘航宇 | — | — | — | — | — | — | 异常 | 2026-06-12 21:40 |
| 刘航宇 | 56.98 | 1.0589 | 0.6849 | 0.3013 | 94.54s | 0.7526 | 已完成 | 2026-06-12 21:44 |
| 刘航宇 | 32.54 | 1.0587 | 0.3357 | 0.3013 | 199.28s | 0.7525 | 已完成 | 2026-06-12 21:54 |
| 刘航宇 | 0 | 2.0749 | 0.6013 | 0 | 119.62s | 0.7361 | 已完成 | 2026-06-12 22:12 |
| 刘航宇 | 51.42 | 1.0587 | 0.6055 | 0.3013 | 118.35s | 0.7525 | 已完成 | 2026-06-13 11:54 |
| 刘航宇 | 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 |
| 刘航宇 | 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 |
| 刘航宇 | 58.45 | 0.9889 | 0.7244 | 0.2579 | 82.67s | 0.7336 | 已完成 | 2026-06-13 13:32 |
| 刘航宇 | — | — | — | — | — | — | 异常 | 2026-06-13 13:55 |
| 刘航宇 | 0 | 1.3450 | 0 | 0 | 307.44s | 0.7506 | 已完成 | 2026-06-13 14:10 |
| 刘航宇 | 53.71 | 1.0589 | 0.6381 | 0.3013 | 108.57s | 0.7524 | 已完成 | 2026-06-13 14:21 |
| 刘航宇 | 55.10 | 1.0587 | 0.6580 | 0.3013 | 102.59s | 0.7525 | 已完成 | 2026-06-13 14:38 |
| 刘航宇 | 58.47 | 1.0589 | 0.7062 | 0.3013 | 88.13s | 0.7526 | 已完成 | 2026-06-13 14:46 |
| 刘航宇 | 55.19 | 1.0589 | 0.6594 | 0.3013 | 102.19s | 0.7526 | 已完成 | 2026-06-14 11:18 |
| 刘航宇 | 58.86 | 1.0589 | 0.7117 | 0.3013 | 86.49s | 0.7526 | 已完成 | 2026-06-14 11:32 |
| 刘航宇 | 58.52 | 1.0589 | 0.7068 | 0.3013 | 87.95s | 0.7526 | 已完成 | 2026-06-14 11:46 |
| 刘航宇 | 58.25 | 1.0589 | 0.7030 | 0.3013 | 89.11s | 0.7526 | 已完成 | 2026-06-14 12:11 |
| 刘航宇 | 58.38 | 1.0589 | 0.7049 | 0.3013 | 88.54s | 0.7526 | 已完成 | 2026-06-14 12:25 |
| qianban139 | 58.05 | 1.0589 | 0.7001 | 0.3013 | 89.96s | 0.7526 | 已完成 | 2026-06-14 23:09 |
| qianban139 | 44.40 | 1.0589 | 0.5052 | 0.3013 | 148.44s | 0.7525 | 已完成 | 2026-06-15 09:19 |
| qianban139 | 62.81 | 1.0589 | 0.7682 | 0.3013 | 69.55s | 0.7525 | 已完成 | 2026-06-15 09:43 |
| 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 |
| qianban139 | 67.87 | 1.0589 | 0.8404 | 0.3013 | 47.88s | 0.7524 | 已完成 | 2026-06-15 14:23 |
| 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 |
团队成员
| AI Studio 用户名 | 真实姓名 |
|---|---|
| qianban139 | 张君硕 |
| sidny1988 | 谢松熹 |
| (队长账号) | 刘航宇 |