目录

jittor-kaisuoshifu-drbgl-b

计图比赛(Jittor)赛道:DRBGL 时序图链接预测 B 榜复现代码,团队「开锁师傅 / locksmith」。

线上总分为 **1.43090**,其中 dataset3=0.86210dataset4=0.56879。本仓库沿用 A 榜的 自适应双分支排序:嵌入部分用 Jittor 训练 BPR-LightGCN,排序部分用 LightGBM LambdaRank 门控,并针对 B 榜的严格时间折做了训练行与权重的适配。

仓库命名遵循规范 jittor-kaisuoshifu-[项目名字],团队名在 GitHub 仓库 slug 中需使用 ASCII,故渲染为 kaisuoshifu / locksmith;项目名取 drbgl-b。 本地文件夹名不影响远程仓库名,如需其它标识可在创建 GitHub 仓库时自行命名。

数据 / 权重说明:本仓库不包含赛方原始数据、预测 CSV、缓存 mmap 与模型权重 (.gitignore 已忽略)。models/manifest.json 只记录线上提交对应文件的 sha256 等 指纹,用于核对自训练产物的同源性。完整流程请按第 3 节从原始数据重跑。

目录结构

.
├── README.md                # 本文件
├── LICENSE                  # MIT 许可证
├── NOTICE                   # 第三方代码 / 数据声明
├── .gitignore / .gitattributes
├── requirements.txt         # 依赖清单
├── configs/                 # 配置(命令行参数优先级更高)
│   ├── infer.yaml           # 默认推理 / 复现配置
│   └── retrain.yaml         # 重训 embedding 后推理
├── src/drbgl_b/             # 核心代码
│   ├── config.py            # 配置读写、随机种子、日志、运行命令
│   ├── pipeline.py          # dataset3 / dataset4 推理流水线
│   ├── data.py              # 数据加载与严格时间切分
│   ├── candidates.py        # 候选构造(源-时间 / 源-度模板)
│   ├── metrics.py           # 排序指标与序数名次映射
│   ├── artifacts.py         # sha256 / JSON / git 元数据工具
│   ├── train.py             # 门控训练数据、帧构造与 LambdaRank 参数
│   ├── train_joint.py       # joint 分支:原始数据准备与辅助块
│   ├── train_natural.py     # natural 时间折训练行与 fold 门控
│   ├── fit_strict_mix.py    # strict / uniform 混合 candidate gate
│   ├── tune_rolling.py      # rolling 折上的 base gate 树数选择
│   ├── tune_recent_folds.py # natural 折 MRR 校验与特征矩阵生成
│   ├── sweep_gate_iterations.py  # 树数量筛选
│   ├── score_val.py         # 本地 MRR 评分工具
│   ├── experts/             # 打分配专家(LightGCN、低保秩、结构 / 曝光…)
│   └── baselines/           # 启发式基线与 depop 家族(v3 / v7 / v9)
├── scripts/                 # 运行脚本(入口)
│   ├── infer.py                  # 推理 / 复现 → CSV + submission_b.zip
│   ├── verify_submission.py      # 校验提交包
│   ├── train_gates.py            # 从原始数据训练初始 base / candidate gate
│   ├── build_joint_blocks.py     # prepare / build / fit(joint 分支)
│   ├── build_natural_folds.py    # prepare / build / fit(natural 折)
│   ├── tune_rolling.py / tune_recent_folds.py / sweep_gate_iterations.py
│   └── fit_strict_mix.py         # 训练线上部署的 candidate gate
├── tools/                   # 工具脚本
│   ├── inspect_data.py           # 数据统计与体检
│   └── score_predictions.py      # 本地 MRR 评分
├── tests/                   # 单元测试(不依赖原始数据)
├── data/                    # 仅放数据说明(原始数据不入库)
├── models/                  # 检查点目录(权重不入库,见 models/README.md)
└── outputs/                 # 日志 / 缓存 / CSV / zip(默认不提交)

1. 环境安装

  • Python 3.9 ~ 3.11(本项目在 3.11 上验证)
  • 安装依赖(Windows / Linux 通用):
pip install -r requirements.txt

依赖包含 jittornumpypandasscipyscikit-learnlightgbmthreadpoolctlPyYAML。Jittor 的安装与 CUDA 配置参考 Jittor 官方文档

硬件建议:dataset4 的全量推理较为吃资源,推荐 ≥128 GB 内存、≥70 GB 可用磁盘; 调小 --inference-batch-size 可以降低峰值内存(耗时增加)。

2. 数据准备

把赛方原始 CSV 放到:

data/
|-- dataset3/
|   |-- train.csv
|   `-- test.csv
`-- dataset4/
    |-- train.csv
    `-- test.csv
  • train.csvsrc,dst,time(历史边,time 为 Unix 秒)
  • test.csvsrc,time,c1,...,c100(每个查询的 100 个候选)

数据根目录通过 --data-rootdata_root 配置项指定(相对路径按仓库根目录解析)。 原始数据已被 .gitignore 忽略,请勿提交。跑流水线前建议先体检:

python tools/inspect_data.py

3. 训练

本仓库不发布权重,因此标准流程是从原始数据训练全部中间产物。所有命令在仓库根目录 执行,中间缓存默认写在 outputs/cache/ 下(--cache-root 可改)。

步骤 1:先有一组「初始门控 + embedding」用于冷启动 bootstrap。

python scripts/train_gates.py --dataset dataset4 --data-root data \
  --output-dir outputs/bootstrap_gates --device cuda

产出:<output-dir>/models/base_gate.txtcandidate_gate.txt; 三组 BPR-LightGCN embedding 写在训练缓存下(形如 <output-dir>/cache/*/models/lightgcn_d64_s42.npz)。把它们复制到 models/

cp outputs/bootstrap_gates/models/base_gate.txt models/base_gate.txt
cp outputs/bootstrap_gates/models/candidate_gate.txt models/candidate_gate.txt
cp outputs/bootstrap_gates/cache/uniform_42/models/lightgcn_*.npz models/

步骤 2:准备 dataset4 原始数组与时间折缓存。

python scripts/build_joint_blocks.py prepare --data-root data
python scripts/build_natural_folds.py prepare --data-root data

步骤 3:用初始检查点跑一次完整 dataset4 推理,生成 natural fold 需要的生产曝光与 多尺度缓存:

python scripts/infer.py --dataset dataset4 --output-dir outputs/bootstrap

步骤 4:构建 strict / uniform 辅助块(strict 30,000 行、uniform 每个种子 20,000 行):

python scripts/build_joint_blocks.py build --dataset dataset4 --kind strict \
  --train-queries 30000 --eval-queries 30000 --device cuda --score-backend jittor
python scripts/build_joint_blocks.py build --dataset dataset4 --kind uniform \
  --train-queries 20000 --device cuda --score-backend jittor

步骤 5:构建 natural 时间折m2/m1/eval 用完整推理路径特征,late 折做稳健性检查):

for fold in m2 m1 eval m1_late eval_late; do
  python scripts/build_natural_folds.py build --fold "$fold" \
    --data-root data --production-cache outputs/bootstrap/cache --device cuda
done

Windows(PowerShell)请用:foreach ($fold in @('m2','m1','eval','m1_late','eval_late')) { ... }

步骤 6:训练 final base gate(rolling-m2,225 棵树)与 candidate gate(1200 棵树)。

python scripts/build_natural_folds.py fit --threads 32
python scripts/tune_rolling.py rolling --base-trees 225 --candidate-trees 1200 --threads 32
python scripts/fit_strict_mix.py \
  --base-model outputs/experiments/natural_dataset4_rolling/rolling_m2/base_gate.txt \
  --strict-weight 0.005 --uniform-weight 0.005 --trees 1200

随后把得到的两个 gate 覆盖到 models/base_gate.txt / candidate_gate.txt)。 models/manifest.json 记录了线上检查点的树数量、维度与 sha256,可用于核对。

完整训练的计算量与内存开销较大(建议 ≥128 GB 内存、≥176 线程的生产机;本机复现请把 --threads 调小)。这一步只做数据规格适配与 checkpoint 选择,A 榜的专家、特征 顺序与 LambdaRank 模型家族均保持不变。

4. 评测 / 推理

一条命令复现 B 榜两份 CSV 并打包:

python scripts/infer.py --config configs/infer.yaml

只跑单个数据集 / 使用其它检查点目录:

python scripts/infer.py --dataset dataset3 --output-dir outputs/ds3
python scripts/infer.py --dataset dataset4 --model-dir models --output-dir outputs/ds4

若两步推理已完成、只想重新打包:

python scripts/infer.py --package-only --output-dir outputs/ds4

校验产物(成员、行数、取值是否为 1~100 的序数名次、sha256):

python scripts/verify_submission.py outputs/submission_b.zip
python scripts/verify_submission.py outputs/submission_b.zip --require-reference-hash

本地 MRR 评分与单元测试:

python tools/score_predictions.py --val <验证折目录> --scores outputs/dataset4.csv
python -m unittest discover -s tests -v

每次运行会在 output_dir 下写出:

文件 内容
config.yaml 本次实际使用的配置(含命令行覆盖后的最终值)
command.txt 本次运行的完整命令
infer.log 日志(含 stdout 与异常回溯)
dataset3.csv / dataset4.csv 提交用结果,每行 100 列序数名次
*_manifest.json 行数、输入 / 权重 sha256、参考哈希、耗时等可复现信息
submission_b.zip 可直接提交的压缩包

5. 结果说明

  • 线上指标:B 榜总分 1.43090dataset3=0.86210dataset4=0.56879),由赛方在 隐藏测试标签上计算,models/manifest.json 记录了对应的提交与 file sha256。
  • 本地可用指标
    • MRRdrbgl_b.metrics.mean_reciprocal_ranktools/score_predictions.py): 对每个查询计算真值的平均倒数排名,用于 checkpoint 选择与折间比较;随机猜测约 0.052(100 候选)。
    • NDCG(label_gain [0, 1]):两个 LambdaRank 门控的训练目标。
  • 提交形式dataset3.csv 157670 行、dataset4.csv 2322538 行,每行 100 列, 取值 0.01~1.00(候选序数名次除以 100,非概率)。 scripts/verify_submission.py 会校验行数、值域与「每行是否为 1~100 的排列」。
  • 与线上成绩的差异说明
    • 仓库不发布权重,--require-reference-hash 只有在你自己训练出与 manifest 记录 完全一致的检查点时才通过;普通复跑会得到结构相同、数值略有差异的结果。
    • --score-backend jittor 改用 Jittor 计算候选点积,浮点累加顺序不同, CSV 可能与参考哈希不一致,但排序质量基本一致(默认 numpy 是位级稳定的路径)。
    • 重训 embedding / 重建 base gate 受 Jittor 版本、是否使用 CUDA、线程数影响, 会有合理波动;base-gate 阶段固定了原生线程池布局 (BASE_GATE_*_THREADS),换机器复算冷启动名次时也可能略有差异。
    • 测试集标签不在原始数据中,本地只能在同源的时间验证折上评测,绝对数值与线上总分 不可直接比较。

6. 可复现说明

  • 随机种子:--seed / runtime.seed(默认 20260820)统一设置 Python / NumPy / Jittor 种子(见 src/drbgl_b/config.py::set_seed),并在 run_dataset3 / run_dataset2 入口统一生效;负采样、抓取 SVD、聚类等环节还各自使用固定种子 (LightGCN 为 42 / 2027)。
  • 每次运行落盘:实际配置 config.yaml、运行命令 command.txt、日志 infer.log, 以及每个数据集的 *_manifest.json(含 sha256 与参考哈希)。
  • 关键参数(数据路径、设备、打分后端、batch size、epoch、学习率、线程数、推理块大小、 是否重训 / 重建)全部来自配置文件或命令行,命令行优先级高于配置文件
  • 入口脚本不写死本机路径:所有路径由 --config 与命令行参数给出,相对路径统一按仓库 根目录解析(缓存默认落在 outputs/cache/,不再依赖 /dev/shm)。
  • 缺失数据、缺失权重、列名不合法、时间边界错误都会抛出带修复提示的异常。

7. 进阶:基线脚本

src/drbgl_b/baselines/ 下的启发式基线与 depop 家族用于对照实验(PYTHONPATH 需包含 src):

# Linux / macOS
PYTHONPATH=src python -m drbgl_b.baselines.depop_v9 --dataset dataset3
# Windows (PowerShell)
$env:PYTHONPATH="src"; python -m drbgl_b.baselines.depop_v9 --dataset dataset3

其中 depop_v9 的 memory 分支仍是 dataset3 线上流程使用的打分实现。 scripts/sweep_gate_iterations.pyscripts/tune_rolling.pyscripts/tune_recent_folds.py 则服务于 checkpoint 选择与本地校验。

8. 第三方声明

本项目使用 Jittor、LightGBM、scikit-learn、SciPy、NumPy、pandas、PyYAML, LightGCN 传播由本仓库自行实现,来源与许可证见 NOTICE。 检查点来源与生成方式见 models/README.md

9. 提交规范

提交信息建议使用前缀:feat: / fix: / docs: / refactor: / chore:。 提交前请确保:代码可运行(python -m unittest discover -s tests)、README 命令真实可用、 未提交原始数据与大文件中间产物。

已知平台问题:Windows 上 unittestTemporaryDirectory 清理可能因 numpy mmap 句柄 报 PermissionError [WinError 32],该报错发生在清理阶段,不影响用例断言; Linux / macOS 下不会出现。

关于
149.0 KB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号