Files
CompanionGuard-RL/code/CLAUDE.md
zhangsiyuan bd1f51c496 chore: initial commit — unified project repo
Merged code repo (CompanionGuard-RL) into single project-level git.
Reorganized root: docs/, reference/, experiments/, tmp/active|archives/.
Gitignored: data/, checkpoints/, .venv, experiment logs, tmp/archives.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:28:42 +08:00

12 KiB
Raw Blame History

CompanionGuard-RL — 远程 4-GPU 训练任务指南

本文件由 Claude Code 自动读取。请严格按阶段顺序执行,每阶段完成后打印一行 === Phase N done === 再继续。


任务目标

在远程 GPU 服务器上完成 Module B — Context-aware Risk Detector 的 4-GPU 分布式训练,产出 checkpoints/detector/best.pt


服务器信息

项目
SSH 命令 ssh -p 20083 root@10.82.3.180
密码 m2dGcwyrhI
GPU 4 × RTX 5090 32 GB
远程工作根目录 /root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/
远程项目目录(以下简称 $PROJ /root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL

重要约束:服务器 Docker 网络受限,部分包无法直接 pip install / wget。 优先尝试国内镜像;若失败,改用本地下载 → scp 传输的离线方式。


Phase 0 — 连接与环境探查

# 探查可用资源ssh 进入后逐条运行)
nvidia-smi                          # 确认 4 块 GPU 都可见
python3 --version || python --version
which conda && conda --version || echo "no conda"
pip3 --version || pip --version
python3 -c "import torch; print(torch.__version__, torch.cuda.device_count())"
python3 -c "import transformers; print(transformers.__version__)"
python3 -c "import accelerate; print(accelerate.__version__)"

记录以下信息用于后续决策:

  • python 命令是 python3 还是 python
  • torch 是否已安装,版本是否 ≥ 2.0
  • transformers / accelerate / peft 是否已安装
  • 是否有 conda

Phase 1 — 项目文件传输

在本地Windows PowerShell / cmd执行 scp将代码与数据传到服务器。

# 1-A 创建远程目录
ssh -p 20083 root@10.82.3.180 "mkdir -p /root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL"

# 1-B 传输源码目录排除缓存与已有checkpoint
scp -P 20083 -r `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\src `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\scripts `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\configs `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\requirements.txt `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/

# 1-C 传输数据集(约 30-50 MB
scp -P 20083 -r `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\data `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/

验证(在服务器上):

cd $PROJ
ls src/ scripts/ configs/ data/processed/CompanionRisk-Bench/
wc -l data/processed/CompanionRisk-Bench/train.jsonl   # 应为 2815
wc -l data/processed/CompanionRisk-Bench/test.jsonl    # 应为 605

Phase 2 — Python 依赖安装

2-A 先尝试国内镜像直接安装

cd $PROJ
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple \
  torch transformers accelerate peft datasets tokenizers \
  scikit-learn tqdm pyyaml omegaconf jsonlines rich \
  openai anthropic wandb

若上述命令报网络错误,转 2-B离线方式

2-B 离线方式(若 2-A 失败)

在本地 Windows 执行(需要本地能访问 PyPI

# 下载所有 wheel 到本地文件夹
pip download -d D:\Myresearch\wheels --platform linux_x86_64 `
  --python-version 310 --only-binary=:all: `
  torch transformers accelerate peft scikit-learn tqdm `
  pyyaml omegaconf jsonlines rich

# 传输 wheels 到服务器
scp -P 20083 -r D:\Myresearch\wheels `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/

在服务器上安装

pip3 install --no-index --find-links=/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/wheels \
  torch transformers accelerate peft scikit-learn tqdm pyyaml omegaconf jsonlines rich

2-C 验证

python3 -c "
import torch, transformers, accelerate, peft, sklearn
print('torch:', torch.__version__, '| cuda gpus:', torch.cuda.device_count())
print('transformers:', transformers.__version__)
print('accelerate:', accelerate.__version__)
print('peft:', peft.__version__)
"

期望:cuda gpus: 4


Phase 3 — MacBERT 模型获取

模型名称:hfl/chinese-macbert-large(约 500 MB

3-A 优先:使用 HuggingFace 国内镜像

cd $PROJ
HF_ENDPOINT=https://hf-mirror.com python3 -c "
from transformers import AutoTokenizer, AutoModel
AutoTokenizer.from_pretrained('hfl/chinese-macbert-large')
AutoModel.from_pretrained('hfl/chinese-macbert-large')
print('MacBERT download OK')
"

若成功,跳过 3-B / 3-C。

3-B 备选ModelScope 下载

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple modelscope
python3 -c "
from modelscope import snapshot_download
snapshot_download('hfl/chinese-macbert-large', cache_dir='$PROJ/model_cache')
"

若成功,修改 configs/detector_config.yaml

model:
  name: "/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/model_cache/hfl/chinese-macbert-large"

3-C 最终备选:本地下载 → scp

在本地 Windows 执行

# 需要本地能访问 HuggingFace 或 hf-mirror
pip install huggingface_hub
python -c "
from huggingface_hub import snapshot_download
snapshot_download('hfl/chinese-macbert-large', local_dir='D:/Myresearch/macbert-large')
"

# 传输到服务器
scp -P 20083 -r D:\Myresearch\macbert-large `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/macbert-large

在服务器上更新配置(见下方 Phase 4


Phase 4 — 配置确认4-GPU Linux 专用)

服务器专用配置已预生成:configs/detector_config_server.yaml num_workers: 4effective batch = 16 × 4 GPUs × 2 accum = 128bf16)。

仅当 Phase 3-C本地 scp 传输模型)时,需要更新 model.name

cd $PROJ

# 仅在 Phase 3-C 时执行:将 model.name 改为本地路径
sed -i 's|name: "hfl/chinese-macbert-large"|name: "/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/macbert-large"|' configs/detector_config_server.yaml

# 确认关键参数
grep -E "num_workers|per_gpu_batch|gradient_accum|mixed_precision|name:" configs/detector_config_server.yaml

Phase 3-A / 3-B 成功时无需修改,直接进入 Phase 5。


Phase 5 — 启动 4-GPU 训练

cd $PROJ
mkdir -p experiments checkpoints/detector

# 推荐accelerate launch使用服务器专用配置
accelerate launch \
  --num_processes=4 \
  --mixed_precision=bf16 \
  --multi_gpu \
  scripts/train_detector.py \
  --config configs/detector_config_server.yaml \
  2>&1 | tee experiments/train_$(date +%Y%m%d_%H%M%S).log &

echo "Training PID: $!"

accelerate launch 不可用,改用 torchrun

torchrun --nproc_per_node=4 \
  scripts/train_detector.py \
  --config configs/detector_config_server.yaml \
  2>&1 | tee experiments/train_$(date +%Y%m%d_%H%M%S).log &

Phase 6 — 监控与验证

训练启动后持续执行以下检查:

# 6-A 查看实时日志关键前100步 loss 应在 1.0~3.0 之间下降)
tail -f experiments/train_*.log

# 6-B GPU 利用率4 块 GPU 利用率均应 >80%
watch -n 5 nvidia-smi

# 6-C 检查第一次验证输出(~100 global steps 后出现)
# 期望 Val binary F1 > 0.40(超过 L1c 基线 0.410 是最低目标,目标 >0.80

# 6-D 检查 checkpoint 保存
ls -lh checkpoints/detector/

Phase 7 — 模型评估(验证 F1=0.9978 是否真实)

背景:训练报告 Val Binary F1=0.9978但该分数基于验证集dev.jsonl 且验证集与训练集同为 LLM 生成,存在"同源过拟合"风险。 本 Phase 用三组实验定位真实泛化能力。

7-A 全量 test 集评估

cd $PROJ

python scripts/evaluate.py \
  --detector-ckpt checkpoints/detector/best.pt \
  --config configs/detector_config_server.yaml \
  --test-data data/processed/CompanionRisk-Bench/test.jsonl \
  --source-filter all \
  --output experiments/eval_all.json

重点观察:

  • binary_f1 是否仍接近 0.9978(若是,说明 test 集也被"污染"
  • level_macro_f1l_risk 0-4 等级 F1——这比 binary 难得多,若也完美则有问题
  • fine_macro_f114 类细粒度标签 F1——最难任务正常应在 0.5-0.8

7-B 仅人工标注子集(关键实验)

python scripts/evaluate.py \
  --detector-ckpt checkpoints/detector/best.pt \
  --config configs/detector_config_server.yaml \
  --test-data data/processed/CompanionRisk-Bench/test.jsonl \
  --source-filter human \
  --output experiments/eval_human_only.json

仅评估来自 DICES / CoSafe / Human-AI Suicide Risk 三个人工标注数据集的样本。 这些样本来源不同于 LLM 生成,能真实反映泛化性。 若此处 binary_f1 明显下降(<0.80),说明模型依赖 LLM 文体特征而非风险语义。

7-C 查看 source 字段分布(调试用)

# 确认 test.jsonl 中 source 字段的实际取值
python3 -c "
import json
from collections import Counter
samples = [json.loads(l) for l in open('data/processed/CompanionRisk-Bench/test.jsonl') if l.strip()]
src_counter = Counter(s.get('source', s.get('id','?')[:10]) for s in samples)
for k, v in sorted(src_counter.items(), key=lambda x: -x[1]):
    print(f'  {k}: {v}')
print(f'Total: {len(samples)}')
"

若输出发现所有样本都没有 source 字段,则 source-filter 用 id 前缀判断evaluate.py 已处理)。 把输出贴回来,若所有样本都是 LLM 生成(无人工标注),说明 test 集设计有问题。

7-D 结果判读标准

实验 binary_f1 解释
7-A 全量 test ~0.99 test/dev 同源,无参考价值
7-A 全量 test ~0.80-0.90 合理,模型有真实泛化能力
7-B 人工标注 ~0.99 可信,真实泛化优秀
7-B 人工标注 0.60-0.75 同源过拟合确认,需处理
7-B 人工标注 <0.60 严重过拟合,训练方案需调整

Phase 9 — 取回结果

训练和评估完成后,将 checkpoint、日志和评估 JSON 传回本地:

# 在本地 Windows PowerShell 执行
scp -P 20083 -r `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/checkpoints `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\

scp -P 20083 -r `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/experiments `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\

# 同时取回更新后的 evaluate.py已修复 bug含 source-filter 功能)
scp -P 20083 `
  root@10.82.3.180:/root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL/scripts/evaluate.py `
  D:\Myresearch\CompanionGuard-RL\code\CompanionGuard-RL\scripts\

关键指标参考(训练目标)

指标 L1c 规则基线(下界) MacBERT 目标
Binary F1 0.410 > 0.80
R1 recall危机类 0.097 > 0.75
R9 recall 0.091 > 0.70
FNR漏检率 0.740 < 0.20

常见问题处理

NCCL 通信报错

export NCCL_P2P_DISABLE=1
export NCCL_IB_DISABLE=1
# 再重新启动 accelerate launch

OOM显存不足不太可能5090 32GB

configs/detector_config.yaml 中将 per_gpu_batch_size: 16 改为 8gradient_accumulation_steps: 4

MacBERT 路径找不到

检查 ~/.cache/huggingface/hub/model_cache/ 目录,找到实际下载路径后更新 config 的 model.name

accelerate 找不到

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple accelerate
# 或用 torchrun 替代(见 Phase 5

文件清单(训练产出)

文件 描述
checkpoints/detector/best.pt 验证集 F1 最高的模型权重
checkpoints/detector/final.pt 最后一个 epoch 的权重
experiments/train_YYYYMMDD_HHMMSS.log 完整训练日志