- Module C: BC+PPO training v5/v6 done; eval results in experiments/eval_intervention_v{5,6}.json
- Reward: v5 label-aligned constrained reward (code/src/rl/reward.py)
- Ablations: Module B (history_r, response_only, full) + Module C (wo_category_reward)
- SOTA baselines: WildGuard and ShieldGemma2b eval scripts and results
- Paper: update sections 05–08 (Module B/C description, experiments table, discussion)
- Docs: add record.md (change log), update state.md and exp.md; retire change.md
- Tools: add html-to-ppt utilities and run_shieldgemma2b.sh
- Configs: add ablation YAML configs for Module B and C
- Cleanup: remove stale reference/ PNG screenshots
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.7 KiB
6.7 KiB
CompanionGuard-RL
为 AI 情感陪伴场景构建检测 + 干预一体化安全流水线,目标期刊 SCI Q1/Q2(IP&M / ESWA)。
系统架构
输入 X = (Persona P, History H, User u_t, AI Response r_t)
↓
[Module B: Context-aware Risk Detector]
backbone: hfl/chinese-macbert-large + CrossAttention
↓
D = (y_risk, l_risk 0-4, c_primary R1-R10, c_fine 14标签)
↓
s_t = StateEncoder(D, e_H_pool, e_P_pool, t_norm) ← obs_dim = 2065
↓
[Module C: RL Intervention Policy π (BC + PPO)]
↓
a_t ∈ {PASS, WARN, REWRITE, REJECT, CRISIS}
Module B frozen:已达 binary_f1=0.9995,不再迭代。
不变量
违反这些规则会导致训练崩溃或结果在概念上错误,不得绕过。
| 规则 | 原因 |
|---|---|
obs_dim = 2065 固定 |
1+5+10+1024+1024+1,改动导致维度不匹配崩溃 |
状态向量用 det_l_risk,不用 GT l_risk |
GT 在部署时不可得;用 GT 导致 train/eval 不一致,指标虚高 |
Module C 训练只能单 GPU(--num_processes=1) |
RTX 5090 上 torch.distributed.barrier() 触发 CUDA illegal memory access |
BC 阶段 tensor 保持 CPU 直到 accelerator.prepare() |
DataLoader(pin_memory=True) 不支持 CUDA tensor |
| Module B 权重 frozen,不参与 Module C 训练 | 检测器是 offline 预处理阶段,不是可微组件 |
行为准则
结果异常:立即暂停并报告
- 任何运行结果与预期明显不符(指标异常高/低、loss 不收敛、输出格式错误)→ 立即停止后续步骤,说明异常现象,不得假设"可能正常"后继续
- eval 数字在两次运行间出现差异 → 先找原因,不得直接取较好的那次结果
- 代码修改后指标反而大幅提升 → 优先怀疑 data leakage 或 bug,而非庆祝
不可逆操作:执行前明确确认
- 删除或覆盖任何文件(checkpoints、experiments/*.json、data/processed/)→ 必须先告知用户将要做什么,得到确认后再执行
- 服务器上的写入 / 覆盖操作 → 操作前说明目标路径和影响范围
- 重新训练 Module B → 需明确讨论(权重 1.35GB、GPU 数十小时,论文结果依赖 frozen 权重)
范围纪律:只做被要求的
- 修复 bug 时不顺手重构周边代码
- 改一处配置时不改动其他超参数
- 不引入未被要求的功能、抽象或依赖
研究诚信
- 论文中的数字必须可追溯到具体实验文件(experiments/*.json)和 checkpoint,不得凭记忆或估算填写
experiments/下的历史结果文件只读;需更新结果时生成新文件(如eval_intervention_v5.json),不覆盖旧文件- 数据集 v4(
data/processed/CompanionRisk-Bench/)已冻结,不得修改任何样本 - 报告结果时不选择性省略不利指标(当前 action_accuracy、crisis_precision 未达标,必须如实陈述)
基础设施变动:立即记录
服务器修复、重置、存储重挂载等事件发生后,必须同步更新以下内容,不得拖到下次出问题才修:
state.md服务器速查表(SSH 命令、认证方式、存储 UUID、代理端口)record.md补变更条目(变了什么、影响哪些文件、教训)- 所有含绝对路径的 config 文件(
configs/intervention_config.yaml、configs/detector_config_server.yaml)——先在服务器上确认新路径,再同步本地
典型触发场景:存储 UUID 变更、SSH 密钥更换、代理端口变化、Python 环境路径变化。
歧义:询问而非假设
- 当操作会影响实验结果或论文内容,且需求存在歧义时,先问清楚再动手
论文论点
核心主张:现有 guard 模型(Llama Guard、WildGuard)只检测不干预,且对 companion-specific 风险系统性漏检。CompanionGuard-RL 在检测基础上学习分级干预动作。
三个贡献:
- CompanionRisk-Bench(9,896 样本)+ 10 类风险分类体系
- Module B:上下文感知检测器,binary_f1=0.9995,FNR=0
- Module C:RL 自适应干预策略,safety_recall=1.0(rule baseline 0.908)
当前 limitation(不能回避,在 discussion 节正面陈述):
- action_accuracy=0.575(目标 ≥0.70),L1 过激主因
- crisis_precision=0.421(目标 ≥0.80),R1 样本稀少主因
文档导航
| 文件 | 内容 | 何时查阅 |
|---|---|---|
state.md |
当前模块状态、v5 执行计划、训练命令 | 每次开始工作前 |
record.md |
历史变更、bug 修复记录、完整实验结果 | 需要了解某个决策来龙去脉时 |
exp.md |
环境问题与解决方案(NCCL、PyYAML、依赖等) | 遇到运行时错误时 |
更新规则:代码改动 → state.md + record.md;环境/崩溃问题 → exp.md;架构或不变量变化 → CLAUDE.md;服务器基础设施变动(UUID、认证、代理)→ state.md + record.md + CLAUDE.md 服务器节。
代码结构
code/
├── src/
│ ├── models/detector.py # Module B(frozen)
│ ├── models/intervention_agent.py # Module C Actor-Critic
│ ├── rl/reward.py # v5 label-aligned constrained reward
│ ├── rl/companion_env.py # 单步 MDP 离线环境
│ ├── rl/ppo_trainer.py # PPO 训练器
│ └── utils/preprocessing.py # build_obs_vector(用 det_l_risk)
├── scripts/
│ ├── train_intervention.py # BC + PPO 主训练脚本
│ └── evaluate.py # 多基线评估(支持 --bc-ckpt ablation)
├── configs/
│ └── intervention_config.yaml # 训练配置(use_wandb: false)
└── tests/
├── test_reward_v5.py
└── test_intervention_metrics.py
服务器
# 连接(别名或完整命令)
ssh server5090
ssh -p 20083 -i C:/Users/张思远/.ssh/ai_tunnel_key root@10.82.3.180
# 路径
$PROJ = /root/siton-data-2849d4ce327c4ccfb233ce33868fe7fe/zsy/CompanionGuard-RL
MacBERT = $PROJ/../macbert-large
Python = /opt/conda/envs/dlapo-py310-cu128/bin/
GPU = 4 × RTX 5090 32GB
# 认证
密钥文件: C:\Users\张思远\.ssh\ai_tunnel_key (ED25519,2026-05-19 配置)
SSH config 别名: ~/.ssh/config → Host server5090
# 代理(服务器无外网,使用本地隧道转发)
服务器内 http_proxy=http://127.0.0.1:7890 用于 pip/curl
验证隧道: netstat -tlnp | grep 7890 → 应有 127.0.0.1:7890 LISTEN
# 存储 UUID(服务器修复/重置后可能变更,需同步更新 configs/ 绝对路径)
当前 UUID: siton-data-2849d4ce327c4ccfb233ce33868fe7fe (2026-05-19 起)
旧 UUID: siton-data-740d234e02d749f08fe5347b0c74c49f (已失效)