# DPO 训练数据设计方案 ## 1. 总体规划 ### 1.1 数据规模 | 数据集 | 用途 | 数量 | 说明 | |--------|------|------|------| | `data/train_pref/` | DPO 训练 | **2500 对** | preference pairs (chosen + rejected) | | `data/dev_pref/` | 验证/早停 | **300 对** | 从训练集中分出 | | `data/benchmark/` | 测试(不动) | 1200 episodes | 已有的,完全隔离 | ### 1.2 隔离原则 ``` Benchmark (测试集) Training (训练集) ───────────────── ───────────────── 35 个场景 (INS-01~05, DF-01~06...) 40 个新场景 (完全不同的 causal pattern) 35 个 FP 变体 40 个新 FP 变体 4 种布局 (A/B/C/D) 4 种新布局 (E/F/G/H) 或同布局不同配置 3 种画像 3 种新画像变体 固定 query 模板 重写的 query 模板 ``` --- ## 2. 训练场景设计(40 个新场景,与 benchmark 的 35 个完全不重叠) ### 2.1 Intrusion 类(8 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-INS-01 | 临时访客码在非预约时段使用 | benchmark INS-05 是被盗凭证,这个是合法码被滥用 | | T-INS-02 | 连续多天同一时间段出现陌生运动模式 | benchmark INS-01 是单次破窗,这个是持续性异常 | | T-INS-03 | 门锁解锁后无对应 occupancy 触发 | benchmark 没有这种"缺失信号"型入侵 | | T-INS-04 | 阳台门深夜打开+室内无对应活动 | benchmark INS-01 是窗户,这个是阳台门 | | T-INS-05 | 多个窗户传感器短时间内依次触发 | benchmark 没有"扫描式"入侵模式 | | T-INS-06 | 门锁被远程解锁但住户手机不在家 | 需要推断"远程操作+无人在家"的矛盾 | | T-INS-07 | 安防系统被 Disarm 但无对应的门锁操作 | 系统被绕过的信号 | | T-INS-08 | 住户出门后家中出现规律性运动(每天同一时间) | 跟 benchmark BA-05 不同——这个是规律性的 | ### 2.2 Fire/Gas 类(6 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-FG-01 | 多个房间温度同时异常上升(非单一热源) | benchmark FG-02 是单房间,这个是全屋 | | T-FG-02 | 灶具关闭后温度持续上升(余热异常) | benchmark FG-01 是忘关火,这个是关了但温度还涨 | | T-FG-03 | 烟雾传感器 ContaminationState 逐步恶化 | benchmark DF-05 是突发故障,这个是渐进退化 | | T-FG-04 | 厨房 CO 浓度缓慢上升(不触发报警阈值) | benchmark FG-03 是直接 COAlarm,这个是亚阈值 | | T-FG-05 | 电器运行时间异常长(洗碗机 3 小时不停) | 可能过热风险 | | T-FG-06 | 多个烟雾报警器的 InterconnectSmokeAlarm 触发 | benchmark 没有互联报警场景 | ### 2.3 Water Damage 类(4 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-WD-01 | 漏水传感器间歇性触发(每隔几小时一次) | benchmark WD-01 是持续触发,这个是间歇性 | | T-WD-02 | 卫生间湿度持续升高但无人使用 | 隐蔽漏水的间接信号 | | T-WD-03 | 洗衣机运行结束后漏水传感器延迟触发 | 排水管问题 | | T-WD-04 | 多个房间的漏水传感器先后触发(水蔓延) | benchmark 只有单点漏水 | ### 2.4 Device Fault 类(8 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-DF-01 | 空调运行但温度不下降(制冷失效) | benchmark 没有空调故障 | | T-DF-02 | 两个相邻房间温度传感器读数差异突然增大 | 交叉验证型故障检测 | | T-DF-03 | 洗衣机 OperationalState=Running 但 CountdownTime 不减少 | benchmark DF-06 是窗帘,这个是洗衣机 | | T-DF-04 | 运动传感器在确认无人时段持续报 Occupied | benchmark DF-03 是周期性,这个是持续性 | | T-DF-05 | 门窗传感器状态与窗帘位置矛盾 | 窗户关着但窗帘显示全开位置 | | T-DF-06 | 温度传感器读数出现物理不可能的跳变 | 瞬间从 23°C 跳到 -5°C | | T-DF-07 | 灯的 OnOff 状态与 LevelControl 矛盾 | OnOff=False 但 Level=200 | | T-DF-08 | 设备频繁离线重连(通信不稳定) | benchmark 没有通信层故障 | ### 2.5 Elderly 类(6 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-EL-01 | 老人连续多天活动范围缩小(只在一个房间) | 渐进性退化 | | T-EL-02 | 老人用餐时间逐步推迟(作息漂移) | benchmark EL-04 是突然不起床,这个是渐变 | | T-EL-03 | 老人夜间在非卧室区域长时间停留 | 可能迷路/意识模糊 | | T-EL-04 | 老人出门频率突然下降(从每天到隔天到不出门) | 社交退缩信号 | | T-EL-05 | 老人做饭时间异常短(从 30 分钟缩短到 5 分钟) | 可能不再正常进食 | | T-EL-06 | 老人半夜反复开关同一个灯 | 可能意识混乱 | ### 2.6 Child 类(4 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-CH-01 | 儿童在家长睡觉后使用厨房电器 | benchmark CH-02 是白天,这个是深夜 | | T-CH-02 | 儿童反复尝试打开被锁定的房间 | 好奇心驱动的危险行为 | | T-CH-03 | 儿童活动区域突然从儿童房转移到阳台 | 高处坠落风险 | | T-CH-04 | 放学后长时间只有浴室有活动信号 | 可能的自伤风险(需谨慎处理) | ### 2.7 Behavioral Anomaly 类(4 个新场景) | ID | 场景名 | 与 benchmark 的区别 | |----|--------|-------------------| | T-BA-01 | 住户回家后不开灯不开空调直接进卧室 | 情绪/健康异常信号 | | T-BA-02 | 设备使用频率突然翻倍(强迫性行为) | benchmark BA-03 是灯光闪烁,这个是全设备 | | T-BA-03 | 住户连续多天不使用厨房(不做饭不吃东西) | 生活能力下降 | | T-BA-04 | 两个住户的活动时间完全不重叠(回避行为) | 家庭关系异常 | --- ## 3. 训练 FP 变体设计原则 每个训练场景都配一个 FP 变体,设计原则: **与 benchmark FP 的区别**: - benchmark 的 FP 是"同一事件的正常解释"(如:窗户打开→住户通风) - 训练集的 FP 要设计"不同但相似的正常模式"(如:临时访客码使用→预约的清洁工按时到达) **FP 难度分层**: - 30% Easy FP:明显正常(有直接的正常证据) - 50% Medium FP:需要推理才能排除(证据模糊) - 20% Hard FP:极其接近 TP(只有一个细微差异) --- ## 4. DPO Pair 构造方案 ### 4.1 Chosen(正确回答)的来源 | 来源 | 比例 | 说明 | |------|------|------| | 规则生成 | 40% | 根据 ground truth 直接构造标准答案(is_anomaly + threat_type + 推理链) | | 强模型生成 | 40% | 用 DeepSeek V4 / Claude 跑训练集,筛选答对且推理链好的 | | 人工编写 | 20% | 对高难度场景手写高质量推理链 | ### 4.2 Rejected(错误回答)的来源 | 来源 | 比例 | 错误类型 | |------|------|---------| | 模型实际错误 | 50% | 用 Qwen3.5-9B baseline 跑训练集,收集错误输出 | | 构造性错误 | 30% | 人工/规则构造典型错误模式 | | 对调错误 | 20% | 把 TP 的 chosen 改成 is_anomaly=false(漏报),把 FP 的 chosen 改成 is_anomaly=true(误报) | ### 4.3 构造性错误的具体类型 ``` 错误类型 1: 漏报(TP 场景判为正常) - "温度波动在正常范围内" ← 实际是 stuck-at 故障 - "运动传感器触发可能是宠物" ← 实际是入侵 错误类型 2: 误报(FP 场景判为异常) - "温度上升可能是火灾" ← 实际是正常做饭 - "凌晨运动可能是入侵" ← 实际是住户失眠 错误类型 3: 类型判错 - 把 sensor_stuck 判成 fire_risk - 把 intrusion 判成 behavioral_anomaly 错误类型 4: 证据编造 - 引用了日志中不存在的事件 - 时间戳引用错误 错误类型 5: 推理链断裂 - 结论跟证据不匹配 - 跳过关键推理步骤 ``` --- ## 5. 数据分布设计 ### 5.1 按场景类别 | 类别 | 训练场景数 | TP pairs | FP pairs | TN pairs | 总 pairs | |------|-----------|----------|----------|----------|----------| | Intrusion | 8 | 400 | 300 | — | 700 | | Fire/Gas | 6 | 250 | 200 | — | 450 | | Water Damage | 4 | 150 | 100 | — | 250 | | Device Fault | 8 | 350 | 250 | — | 600 | | Elderly | 6 | 150 | 100 | — | 250 | | Child | 4 | 100 | 80 | — | 180 | | Behavioral | 4 | 100 | 70 | — | 170 | | TN (纯正常) | — | — | — | 200 | 200 | | **合计** | **40** | **1500** | **1100** | **200** | **2800** | ### 5.2 按难度分布 | 难度 | 比例 | 说明 | |------|------|------| | L1 (直接信号) | 20% | 让模型学会"有报警就报" | | L2 (推理检测) | 45% | 核心训练重点 | | L3 (复合推理) | 35% | 提升上限 | ### 5.3 按错误类型分布 | Rejected 错误类型 | 比例 | 目的 | |------------------|------|------| | 漏报 | 35% | 提升 Recall | | 误报 | 30% | 降低 FA | | 类型判错 | 15% | 提升 threat_type 准确率 | | 证据编造 | 10% | 提升推理链质量 | | 推理断裂 | 10% | 提升推理链质量 | --- ## 6. Query 模板隔离 ### Benchmark 的 query(不能用于训练): ``` SQ1: "请检查以下设备状态历史,判断 {room} 区域的传感器是否工作正常。" SQ2: "以下是刚刚发生的事件。请判断这是否构成安全威胁,并说明理由。" SQ3: "以下是过去 {N} 小时的设备活动日志。请分析是否存在异常行为模式。" ``` ### 训练集的 query(重写,同任务不同措辞): ``` SQ1 等价: "根据以下传感器数据记录,评估 {device_name} 的工作状态是否正常。" SQ2 等价: "系统记录了以下设备状态变化。请评估这些变化是否指示安全风险。" SQ3 等价: "以下是 {time_range} 内的设备活动记录。请识别其中是否存在可疑模式。" SQ4 等价: "综合以下多个设备的状态信息,评估家庭整体安全状况。" SQ5 等价: "监控系统标记了潜在异常。请分析情况并建议应对措施。" ``` --- ## 7. 布局隔离方案 ### 方案 A(推荐):同布局不同设备配置 复用 Layout A/B/C/D 的房间结构,但: - 设备数量不同(比如训练集的 Layout A 有 2 个温度传感器而非 3 个) - 设备位置不同(比如烟雾报警器在卧室而非厨房) - 增加 benchmark 没有的设备(如加湿器、扫地机器人的运行状态) ### 方案 B:全新布局 - Layout E: 复式楼(上下两层) - Layout F: 开放式公寓(厨房客厅一体) - Layout G: 合租房(多个独立卧室共用客厅厨房) - Layout H: 带地下室的独栋 **我建议用方案 A**——因为布局本身不是训练重点,设备配置的微调就够了,省工作量。 --- ## 8. 实施步骤 ``` Step 1: 写 40 个新场景的 JSON 模板 (data/train_pref/scenarios/) Step 2: 写 40 个对应的 FP 变体 Step 3: 修改 generate.py 支持从训练场景库生成 episodes Step 4: 生成 2800 个训练 episodes Step 5: 用 Qwen3.5-9B baseline 跑训练集,收集 rejected Step 6: 用 DeepSeek/Claude 跑训练集,收集 chosen Step 7: 组装 DPO pairs (chosen + rejected) Step 8: QLoRA DPO 训练 Qwen3.5-9B Step 9: 在 benchmark 1200 上评测 ``` --- ## 9. 预期效果 | 指标 | 训练前 (EDRC) | 训练后 (DPO) 预期 | |------|-------------|-----------------| | Recall | 80.5% | **75-85%**(保持) | | FA% | 64.3% | **25-35%**(大幅下降) | | F1 | 0.628 | **0.70-0.78** | | Threat Type Acc | ~50% | **65-75%** | DPO 的核心价值不是提升 Recall(EDRC 已经 80%),而是**在保持 Recall 的同时大幅降低误报**——因为训练数据中 30% 的 rejected 是误报案例,模型会学到"什么时候不该报"。 --- ## 10. 风险与缓解 | 风险 | 概率 | 缓解 | |------|------|------| | 训练后 Recall 下降 | 中 | rejected 中 35% 是漏报案例,平衡训练信号 | | 过拟合训练场景 | 中 | 训练/测试场景完全隔离 + dev set 早停 | | 2×A100 显存不够 | 低 | QLoRA 4-bit,9B 模型只需 ~12GB | | DPO 训练不稳定 | 低 | 用 TRL 的 DPOTrainer,成熟框架 | | 效果不如预期 | 中 | 先跑 500 对 pilot,看趋势再扩 |