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>
12 KiB
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: 4,effective batch = 16 × 4 GPUs × 2 accum = 128,bf16)。
仅当 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_f1(l_risk 0-4 等级 F1)——这比 binary 难得多,若也完美则有问题fine_macro_f1(14 类细粒度标签 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 改为 8,gradient_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 |
完整训练日志 |