Skip to content

Repository files navigation

Tencent UNI-REC Challenge 方案开源

这是我在 TAAC 2026 腾讯广告算法大赛 UNI-REC 赛道中的实验代码和复盘记录。最终方案是单模型、单 checkpoint、单推理流程,没有使用 ensemble。

最终分数

指标 数值
训练后 AUC 0.867879
Public AUC 0.830964
推理时间 403.25s

第 30 轮最高分截图

相对初始 baseline 0.806617,最终 public AUC 提升 +0.024347

最终配置

python3 -u "${SCRIPT_DIR}/train.py" \
    --ns_tokenizer_type rankmixer \
    --user_ns_tokens 5 \
    --item_ns_tokens 2 \
    --num_queries 2 \
    --ns_groups_json "" \
    --emb_skip_threshold 1000000 \
    --use_global_time_features \
    --use_dense_group_projector \
    --loss_type focal \
    --focal_alpha 0.25 \
    --focal_gamma 0.25 \
    --eval_every_n_steps 2000 \
    --num_workers 8 \
    "$@"

最高分模型架构

flowchart TB
    A["TencentGR Parquet<br/>user / item / timestamp / sequences"] --> B["PCVRParquetDataset<br/>schema 对齐、padding、序列截断"]

    B --> U0["User Int Sparse<br/>46 fids"]
    U0 --> U1["RankMixerNSTokenizer<br/>5 user NS tokens"]

    B --> I0["Item Int Sparse<br/>14 fids"]
    I0 --> I1["RankMixerNSTokenizer<br/>2 item NS tokens"]

    B --> D0["User Dense<br/>61, 87, 62-66, 89-91"]
    D0 --> D1["DenseGroupProjector<br/>分组投影 + gate 融合<br/>1 个 user dense token"]

    B --> S0["Behavior Sequences<br/>seq_a / seq_b / seq_c / seq_d"]
    S0 --> S1["Per-domain Transformer Encoders"]
    S1 --> Q0["MultiSeqQueryGenerator<br/>2 queries per domain"]

    B --> T0["Global Timestamp"]
    T0 --> T1["day/week sin-cos<br/>Global Time Projection"]

    U1 --> H["MultiSeqHyFormerBlock x2<br/>RankMixer full interaction<br/>d_model=64, heads=4"]
    I1 --> H
    D1 --> H
    Q0 --> H

    H --> R0["Final Representation"]
    T1 --> R0
    R0 --> C0["MLP Classifier"]
    C0 --> O0["Sigmoid Prediction"]

    O0 --> L0["Focal Loss<br/>alpha=0.25, gamma=0.25"]
    O0 --> E0["Step-level Validation<br/>eval_every_n_steps=2000"]
    E0 --> P0["single model.pt<br/>public AUC 0.830964"]
Loading

主要提分点

轮次 改动 Public AUC 说明
1 第一轮 best baseline 0.812437 RankMixer + user_ns=5,item_ns=2,num_queries=2
6 全局时间特征 0.818828 加入当前样本 timestamp 的日周期、周周期信息
10 Focal Loss 0.825397 最终采用 alpha=0.25,gamma=0.25
15 User dense 分组 projector 0.829808 将 dense 61、87、62-66、89-91 分组建模后 gate 融合
30 Step-level validation 0.830964 eval_every_n_steps=2000,选择更稳的 checkpoint

改动细节

1. 全局时间特征

原始行为序列里有 time bucket,但缺少当前样本在全局时间中的位置。第 6 轮加入当前 timestamp 的日周期和周周期 sin/cos 特征后,public AUC 从 0.812437 提升到 0.818828

2. Focal Loss

第 8-12 轮只调 focal 参数。gamma=1.0 -> 0.5 -> 0.25 连续涨分,但 gamma=0.1 掉分,最后保留温和版本:

--loss_type focal
--focal_alpha 0.25
--focal_gamma 0.25

3. User Dense 分组

官方 demo 字段分析显示,user dense 不是同一种语义。原来所有 dense 直接拼接进一个 Linear,容易把 embedding 类特征和统计类特征混在一起。最终改成分组 projector:

dense 61    -> projector
dense 87    -> projector
dense 62-66 -> projector
dense 89-91 -> projector
group vectors -> gate fusion -> 1 个 user_dense token

这个改动不新增 RankMixer token,只改变 dense token 内部建模方式,是后期最明显的提分点之一。

4. Step-level checkpoint selection

第 30 轮只新增:

--eval_every_n_steps 2000

public AUC 从第 18 轮的 0.830596 提升到 0.830964。后续测试 1000 反而略低,说明更频繁验证不一定更好,容易选到本地 valid 噪声。

主要失败方向

后期很多看起来合理的方向都没有迁移到 public:

  • valid_ratio=0.05
  • 更改 NS token 配比
  • 提高 lr
  • day bucket / sequence length 特征
  • missing indicators
  • dense stat log1p
  • CDF 推荐的 seq_c=256
  • global time scale down
  • warmup + cosine scheduler
  • raw item id hash
  • DIN-lite
  • sequence hash embedding
  • user dense wide logit
  • GroupNSTokenizer
  • target-aware query pooling
  • user sparse-dense pair residual

一个比较明显的现象是:有些实验训练 AUC 更高,但 public AUC 掉很多。后期瓶颈不是单纯提升模型表达能力,而是控制 local-public gap。

完整 35 轮实验细节见:

docs/第一轮以来提交实验记录.md

文件说明

文件 说明
run.sh 官方平台训练入口,当前为最高分配置
train.py 参数解析、数据构建、模型构建、训练入口
trainer.py 训练循环、早停、step validation、checkpoint 保存
infer.py 官方推理入口,单 checkpoint 推理
dataset.py Parquet 数据读取、schema、padding、截断
model.py PCVRHyFormer、RankMixer、dense group projector
seq_truncation_ablation_cdf.py 序列截断长度分析工具,不参与最终推理
docs/第一轮以来提交实验记录.md 每一轮实验参数、分数和结论
docs/demo_1000字段分析.md 官方 demo 字段分析

分支说明

分支 说明
main 最终开源分支,README 和 run.sh 面向复现最高分配置
experiment/best-training lizuju 的测试分支,保留更多实验过程和失败方向
origin/dev zhudachang234 的测试分支,包含更激进的探索尝试
original 历史保留分支

复现说明

完整训练数据不在仓库中,需要在官方平台通过 TRAIN_DATA_PATH 读取。Hugging Face demo 数据只用于字段结构分析,不代表完整训练集分布。

本地可以做基础检查:

bash -n run.sh
PYTHONDONTWRITEBYTECODE=1 python3 -m py_compile dataset.py train.py infer.py trainer.py model.py seq_truncation_ablation_cdf.py
git diff --check

About

TAAC 2026 腾讯广告算法大赛 学术赛道 分数0.830964

Topics

Resources

Stars

40 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages