chore(ts-as-modality): scaffold OpenSpec change & adopt reviewed design
- OpenSpec change: proposal/design/tasks + 3 delta specs (ts-synthesis, ts-multimodal-model, ts-evaluation; 21 requirements) - comet state initialized (phase=build), plan recorded - adopt existing reviewed design doc as Design Doc (+ comet frontmatter) - existing implementation plan (+ comet frontmatter) - workspace .gitignore
This commit is contained in:
@@ -87,6 +87,7 @@ coverage/
|
||||
.pi/logs/
|
||||
|
||||
# Claude Code local runtime
|
||||
.claude/settings.local.json
|
||||
.claude/sessions/
|
||||
.claude/cache/
|
||||
.claude/logs/
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
change: ts-as-modality
|
||||
design-doc: docs/superpowers/specs/2026-06-29-ts-as-modality-design.md
|
||||
base-ref: 7a5a1d033fb1ac20af25a17a571b2791694bd923
|
||||
---
|
||||
|
||||
# 时序作为模态的多模态模型 · 实现计划
|
||||
|
||||
> **对应规格**:`docs/superpowers/specs/2026-06-29-ts-as-modality-design.md`
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
---
|
||||
comet_change: ts-as-modality
|
||||
role: technical-design
|
||||
canonical_spec: openspec
|
||||
---
|
||||
|
||||
# 时序作为模态的多模态模型 · 设计规格
|
||||
|
||||
> **日期**:2026-06-29
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
workflow: full
|
||||
phase: build
|
||||
context_compression: off
|
||||
build_mode: executing-plans
|
||||
build_pause: null
|
||||
subagent_dispatch: null
|
||||
tdd_mode: tdd
|
||||
review_mode: standard
|
||||
isolation: branch
|
||||
verify_mode: null
|
||||
auto_transition: true
|
||||
base_ref: 7a5a1d033fb1ac20af25a17a571b2791694bd923
|
||||
design_doc: docs/superpowers/specs/2026-06-29-ts-as-modality-design.md
|
||||
plan: docs/superpowers/plans/2026-06-29-ts-as-modality-plan.md
|
||||
verify_result: pending
|
||||
verification_report: null
|
||||
branch_status: pending
|
||||
created_at: 2026-06-29
|
||||
verified_at: null
|
||||
archived: false
|
||||
handoff_context: openspec/changes/ts-as-modality/.comet/handoff/design-context.json
|
||||
handoff_hash: 067d854db86de682b8c5e173888ab9b0d890244bf938aef24512ec8287789be7
|
||||
@@ -0,0 +1,41 @@
|
||||
# Brainstorm Summary
|
||||
|
||||
- Change: ts-as-modality
|
||||
- Date: 2026-06-29
|
||||
|
||||
## 确认的技术方案
|
||||
|
||||
采纳既有、已评审 Design Doc `docs/superpowers/specs/2026-06-29-ts-as-modality-design.md` 为本次 change 的 Design Doc(comet-design 前置条件「无 Design Doc」被既有文件违反,实质性深度设计已完成,无需重新 brainstorm 出重复文档)。
|
||||
|
||||
核心技术方案(源自 Design Doc):
|
||||
- 路线:ChatTS「时序作为新模态」—— Patch-Project + 轻量编码器(优于 Chronos 时序 Tokenization、Time-LLM Reprogramming)
|
||||
- 骨干:Qwen2.5-0.5B-Instruct(hidden=896)
|
||||
- TS Encoder:Patchify(P=8, stride=4, 通道独立) + 2 层 Transformer(d=256, 4 头, ~4M)
|
||||
- Projector:Linear(256→896) + LayerNorm
|
||||
- 多模态拼接顺序:`[属性][时间戳][TS token][事件][问题]`
|
||||
- 两阶段训练:①冻结 LLM 训 Encoder+Projector(~4.2M,省显存关键)→ ②叠加 LoRA r=16(q/v_proj) SFT(~7M)
|
||||
- 数据:CPU 离线合成为主(50万对齐 + 10万 SFT + 2k held-out),真实 benchmark(SMD/MSL/SMAP/SWaT/PSM) 仅锚定评测
|
||||
- 评测:VUS-PR 为主(严守 MTSAD 纪律,PA-F1 仅对照),LLM-judge + 规则解析双轨,4 类同口径基线
|
||||
|
||||
## 关键取舍与风险
|
||||
|
||||
- [对比损失默认] 采用「扰动一致性 + λ=0.1」作为默认,做成可配置;若 M3「TS-token 有效性检验」(扰动后回答变化率 >50%)失败再换 InfoNCE。
|
||||
- [DPO] 首版不做,M5 后视效果决定。
|
||||
- [高风险·合成→真实泛化] 阶段②掺真实 benchmark 改写样本;评测以真实 benchmark 为准。
|
||||
- [中风险·阶段② 12GB OOM] 降批量/ctx、CPU offload、adamw_8bit、退回阶段①-only 报告。
|
||||
- [中风险·LLM 忽略 TS token] 对比损失 + 必看时序样本 + 消融定位。
|
||||
- [中风险·JSON 解析失败] 训练强化格式约束 + 解析兜底(失败→全 0 计漏报)+ 单独报解析成功率。
|
||||
|
||||
开放问题(TS Encoder 层/d、Patch P、对比损失形式、DPO、真实改写数量)均延后为 build 阶段经验/流程项,不阻塞设计。
|
||||
|
||||
## 测试策略
|
||||
|
||||
- 单元测试:各模块(attributes/synthesis/instruct/ts_encoder/projector/multimodal/collator/losses/parse/ts_metrics)给定 seed 确定性 + 形状/参数量校验
|
||||
- 冒烟路径:`gen_synthetic.py --n 200` → T2.1-T2.4 单 batch → stage1/stage2 `--max_steps 50` → run_eval.sh 产报告骨架,确认端到端通后再放大
|
||||
- 里程碑出口验证:M1-M5 每阶段有可执行完成判据
|
||||
- 评测:异常检测 VUS-PR/Aff-F1/AUC-PR/Point-F1(无PA) + PA-F1(对照);问答 LLM-judge + 规则解析;含 trivial 基线对照防虚高
|
||||
- 可验证成功标准(§6.5):阶段②峰值显存 ≤11GB;真实 benchmark VUS-PR 显著优于纯 LLM 基线;时序消融后指标下降;问答均分超基线;评测可复现
|
||||
|
||||
## Spec Patch
|
||||
|
||||
无。4 项高风险均有对应 delta spec 验收场景闭环;成功标准由 tasks M5.6 出口验证承载,不另开第二份需求 spec。
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"change": "ts-as-modality",
|
||||
"phase": "design",
|
||||
"mode": "compact",
|
||||
"canonical_spec": "openspec",
|
||||
"generated_by": "comet-handoff.sh",
|
||||
"context_hash": "067d854db86de682b8c5e173888ab9b0d890244bf938aef24512ec8287789be7",
|
||||
"files": [
|
||||
{ "path": "openspec/changes/ts-as-modality/proposal.md", "sha256": "d29658df95f49b889a7f06e6985776ba944f2476eca8e06f074787e823408f4e" },
|
||||
{ "path": "openspec/changes/ts-as-modality/design.md", "sha256": "5b920360b1303fde23795a3388c34a11c0c562daa340de12980ff86a1d199f7b" },
|
||||
{ "path": "openspec/changes/ts-as-modality/tasks.md", "sha256": "8e13037661b54a1579cc1c9c81ff2676aee777ca25303ef54c944ce91e852726" },
|
||||
{ "path": "openspec/changes/ts-as-modality/specs/ts-evaluation/spec.md", "sha256": "1c986559a6b44900bff452e4cbbb0272c1ee321de2fddacedc6e096c4e5381fb" },
|
||||
{ "path": "openspec/changes/ts-as-modality/specs/ts-multimodal-model/spec.md", "sha256": "f40631b2e8dac3772f6081623d2175460ca5355a8818d6cb3c28a94f148d56a3" },
|
||||
{ "path": "openspec/changes/ts-as-modality/specs/ts-synthesis/spec.md", "sha256": "330043d178e344f1f1e87d1262f25ed33b2216eb6e16f2658d4f29a779d8b60b" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
# Comet Design Handoff
|
||||
|
||||
- Change: ts-as-modality
|
||||
- Phase: design
|
||||
- Mode: compact
|
||||
- Context hash: 067d854db86de682b8c5e173888ab9b0d890244bf938aef24512ec8287789be7
|
||||
|
||||
Generated-by: comet-handoff.sh
|
||||
|
||||
OpenSpec remains the canonical capability spec. This handoff is a deterministic, source-traceable context pack, not an agent-authored summary.
|
||||
|
||||
## openspec/changes/ts-as-modality/proposal.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/proposal.md
|
||||
- Lines: 1-33
|
||||
- SHA256: d29658df95f49b889a7f06e6985776ba944f2476eca8e06f074787e823408f4e
|
||||
|
||||
```md
|
||||
## Why
|
||||
|
||||
当前 AIOps 场景下,多变量时序的异常检测与解释仍依赖专用模型,缺乏「以自然语言对时序提问、做根因/事件关联推理」的统一能力。基于 `MTSAD-技术深度调研报告.md`,沿用 ChatTS「时序作为新模态」路线,我们希望在**单张 3060 12GB 消费级显卡**上做一个可复现的实验性落地,验证「把多变量时序视为独立模态、与文本/事件模态联合注入小型 LLM」这一方法在算力受限条件下是否切实可行、且「时序模态」是否真带来可量化的增益。现在做是因为:0.5B 级开源 LLM 与 PEFT/LoRA 工具链已足够成熟,使该实验在消费级硬件上首次成为可能。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **新增**:CPU 离线合成数据管线(成分模型 + 异常注入 + 事件耦合 + Evol-Instruct 指令/回答生成),产出对齐预训练与 SFT 用的 JSONL
|
||||
- **新增**:真实 benchmark(SMD/MSL/SMAP/SWaT/PSM)窗口加载与「异常段→问答对」改写(仅评测用,不进训练)
|
||||
- **新增**:TS Encoder(Patchify + 2 层 Transformer)+ Projector(Linear→LLM hidden),把时序编码为独立 soft token
|
||||
- **新增**:多模态拼接器,按 `[属性][时间戳][TS token][事件][问题]` 顺序组装文本 token 与 TS token 注入 LLM
|
||||
- **新增**:两阶段训练流程 —— 阶段①冻结 LLM 训 Encoder+Projector(对齐预训练);阶段②叠加 LoRA(r=16) 做指令微调
|
||||
- **新增**:评测套件 —— 文本回答→JSON 区间→逐点分数解析;VUS-PR(主)/Affiliation-F1/AUC-PR/Point-F1(无PA);LLM-judge + 规则解析双轨
|
||||
- **新增**:4 类同口径对照基线(纯 LLM 数值喂文本 / Time-LLM 风格重映射 / ChatTS(若可复现) / Trivial)
|
||||
- 骨干选用 **Qwen2.5-0.5B-Instruct**,BF16 + LoRA + 梯度检查点,目标阶段②峰值显存 ≤11GB
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `ts-synthesis`: CPU 离线合成数据管线——成分模型(趋势/周期/基线/噪声)、异常注入(尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移)、事件耦合、缺失/不规则模拟、属性词表采样,以及 Evol-Instruct 多轮指令与回答生成;附带真实 benchmark 加载与问答改写
|
||||
- `ts-multimodal-model`: 时序作为模态的多模态模型——TS Encoder + Projector + 多模态拼接(TS token 与文本/事件 token 联合注入 LLM),含阶段①对齐预训练与阶段②LoRA SFT 的训练/推理统一封装
|
||||
- `ts-evaluation`: 时序问答与异常检测评测套件——回答解析(文本→JSON 区间→逐点分数)、阈值无关指标(VUS-PR 主/Affiliation-F1/AUC-PR/Point-F1 无 PA)、LLM-judge + 规则双轨、4 类同口径基线对照、可复现评测报告
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- 无已存在 capability 的需求变更(本项目 specs/ 当前为空)。 -->
|
||||
|
||||
## Impact
|
||||
|
||||
- **新增代码**:独立 Python 项目 `ts-as-modality/`(`pyproject.toml` + `src/tsmm/{data,model,train,eval,utils}` + `scripts/` + `tests/` + `configs/`),与当前 spec/docs 工作区并列
|
||||
- **依赖**:torch、transformers、peft、accelerate、datasets、numpy、tqdm、pyyaml、pytest;评测依赖 `tsb_uad`(VUS-PR);LLM-judge 评测时调用 OpenAI/GPT-4o API
|
||||
- **模型资产**:Qwen2.5-0.5B-Instruct 骨干(外部下载);阶段①/② checkpoint 与合成数据产物体积较大,需 git-ignore(`data/`、`checkpoints/`)
|
||||
- **算力**:单张 3060 12GB;阶段①预估峰值 ~4-5GB,阶段②预估峰值 ~9-10GB;CPU 多进程用于离线合成
|
||||
- **存储**:合成数据约 2-3GB(流式加载),checkpoint 分阶段独立存放
|
||||
- **无 BREAKING 变更**:纯新增独立实验项目,不触碰现有任何代码/接口
|
||||
```
|
||||
|
||||
## openspec/changes/ts-as-modality/design.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/design.md
|
||||
- Lines: 1-88
|
||||
- SHA256: 5b920360b1303fde23795a3388c34a11c0c562daa340de12980ff86a1d199f7b
|
||||
|
||||
[TRUNCATED]
|
||||
|
||||
```md
|
||||
## Context
|
||||
|
||||
本 change 在**单张 3060 12GB 消费级显卡**上做一个可复现的实验性落地:把**多变量时序视为独立模态**,与文本/事件模态联合注入小型 LLM(Qwen2.5-0.5B-Instruct),端到端任务是**时序问答与推理**(ChatTS 路线)。
|
||||
|
||||
背景与约束来自 `MTSAD-技术深度调研报告.md` 与 `docs/superpowers/specs/2026-06-29-ts-as-modality-design.md`(已通过设计评审)。核心约束:
|
||||
|
||||
- **算力**:单卡 12GB → 骨干 ≤0.5B、依赖 LoRA/QLoRA + 短上下文 + 小批量 + 梯度检查点
|
||||
- **数据**:合成数据为主(CPU 离线生成)→ 评测锚定真实 benchmark,防合成过拟合
|
||||
- **目标**:不追学术 SOTA,追「12GB 跑通、可复现、时序模态确有增益」的可验证结论
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 全流程单卡 3060 12GB 跑通,阶段②峰值显存 ≤11GB
|
||||
- TS Encoder + Projector 把时序编码为独立 soft token,使 LLM「能读懂」时序
|
||||
- 时序模态带来可量化增益:真实 benchmark VUS-PR 显著优于纯 LLM 数值喂文本基线;时序消融后指标明显下降
|
||||
- 6 类问答任务(描述/异常/根因/预测/比较/事件关联)LLM-judge 均分超纯 LLM 基线
|
||||
- 评测可复现:含 trivial 基线对照、标注是否用 PA、严守 MTSAD 报告评估纪律
|
||||
|
||||
**Non-Goals:**
|
||||
- ❌ 不从零预训练 LLM(成本不允许,且非本实验目的)
|
||||
- ❌ 不做多卡分布式训练(单卡约束)
|
||||
- ❌ 不追求学术 SOTA 排名
|
||||
- ❌ 不做端侧部署优化(先验证方法)
|
||||
- ❌ DPO 首版不做(M5 后视效果再决定)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 决策 1:采用 Patch-Project + 轻量编码器,而非时序 Tokenization 或 Reprogramming
|
||||
|
||||
时序切 patch(P=8, stride=4,通道独立)→ 2 层 Transformer 编码器(d=256, 4 头, ~4M)→ 线性投影(256→896)成独立 TS token,作为可学习 soft token 注入 LLM。
|
||||
|
||||
**对比的备选方案:**
|
||||
|
||||
| 方案 | 含义 | 取舍 |
|
||||
|------|------|------|
|
||||
| **A(选用)Patch-Project + 轻量编码器** | patch→小编码器→线性投影成独立 TS token | 真正的"时序作为模态";12GB 可训;patch 捕捉局部结构、变长友好。代价:需训编码器+投影层(已在显存预算内) |
|
||||
| B 时序 Tokenization(Chronos 风格) | 数值量化成离散 token、扩展词表 | 最"时序即语言",但量化丢精度、异常细节易损;逐点 token 序列长,12GB 上下文吃紧。放弃 |
|
||||
| C Reprogramming(Time-LLM 风格) | 冻结 LLM 用文本原型重映射 | 参数最省,但受限于已有文本嵌入流形、表达力弱,时序算不上"真新模态",复杂推理/事件联合弱。放弃 |
|
||||
|
||||
### 决策 2:骨干选 Qwen2.5-0.5B-Instruct
|
||||
|
||||
0.5B 中英均衡、有现成 Instruct 版、社区生态成熟;BF16 约 1GB,12GB 余量充足(hidden=896)。
|
||||
|
||||
### 决策 3:两阶段训练,阶段①冻结 LLM
|
||||
|
||||
- **阶段① 对齐预训练**:冻结 LLM,仅训 TS Encoder + Projector(~4.2M 全参)→ 不存 LLM 优化器状态/梯度,是 12GB 可行的关键省显存技巧
|
||||
- **阶段② SFT**:在此之上叠加 LoRA r=16(q/v_proj,~2-3M),LLM 其余冻结 + 梯度检查点
|
||||
|
||||
分阶段 checkpoint 互不污染、可回滚。损失仅对回答段 token 计 LM loss;阶段①叠加对比损失(扰动时序→回答应变)防止 LLM 忽略 TS token。
|
||||
|
||||
### 决策 4:输入拼接顺序 `[属性][时间戳][TS token][事件][问题]`
|
||||
|
||||
属性先给语义,时序居中,事件定位在对应时间,问题在末尾便于回答。
|
||||
|
||||
### 决策 5:合成数据为主,真实 benchmark 仅用于评测锚定
|
||||
|
||||
合成管线全 CPU 离线,成分参数随机化;**核心红利**:异常段、事件时间戳、各成分参数全部作为 ground-truth 自动记录——免费且精确的标签。评测锚定 SMD/MSL/SMAP/SWaT/PSM 真实分布,避免「合成上 SOTA、真实上崩盘」。
|
||||
|
||||
### 决策 6:评测指标以 VUS-PR 为主,严守 MTSAD 报告纪律
|
||||
|
||||
- 主指标 **VUS-PR**(阈值无关);辅 Affiliation-F1(多 λ)、AUC-PR、Point-F1(无 PA)
|
||||
- **PA-F1 仅作对照、不得作主指标**(防虚高)
|
||||
- 问答用 LLM-judge + 规则解析双轨
|
||||
- 自然语言回答→约束 JSON 区间→逐点分数,便于数值化评测
|
||||
|
||||
### 决策 7:4 类同口径基线
|
||||
|
||||
纯 LLM 数值喂文本(检验 TS 模态是否真有增益)、Time-LLM 风格重映射、ChatTS(若可复现)、Trivial(Random/Constant/全报异常)。全部走同一套解析+指标脚本。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [12GB 阶段②仍 OOM] → 降批量/上下文、开 CPU offload 优化器、`adamw_8bit`、退回阶段①-only 报告
|
||||
- [合成→真实泛化差距大(高风险)] → 阶段②掺真实 benchmark 改写样本;评测以真实 benchmark 为准
|
||||
- [LLM 忽略 TS token] → 对比损失 + "必看时序"样本 + 消融实验定位
|
||||
- [回答 JSON 解析失败率高] → 训练强化格式约束 + 解析兜底(失败→全 0 计漏报)+ 单独报解析成功率
|
||||
- [GPT-4o judge 成本] → 仅评测 2k 样本调用;可换开源 judge 做 sanity
|
||||
- [TS Encoder 过拟合合成分布] → 成分参数随机化 + 多套合成配置 + 阶段②引入真实改写样本
|
||||
|
||||
## Open Questions
|
||||
```
|
||||
|
||||
Full source: openspec/changes/ts-as-modality/design.md
|
||||
|
||||
## openspec/changes/ts-as-modality/tasks.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/tasks.md
|
||||
- Lines: 1-45
|
||||
- SHA256: 8e13037661b54a1579cc1c9c81ff2676aee777ca25303ef54c944ce91e852726
|
||||
|
||||
```md
|
||||
# Tasks · ts-as-modality
|
||||
|
||||
> 源自 `docs/superpowers/plans/2026-06-29-ts-as-modality-plan.md`(M1→M5)。
|
||||
> 每个里程碑末尾的「出口验证」为该阶段完成判据;建议先跑「冒烟路径」确认端到端通,再放大到全量。
|
||||
|
||||
## 1. M1 · 数据管线
|
||||
|
||||
- [ ] 1.1 项目脚手架:创建 `pyproject.toml`(torch/transformers/peft/accelerate/datasets/numpy/tqdm/pyyaml/pytest)、`src/tsmm/` 模块骨架、`configs/`、`scripts/`、`tests/`,并建 `data/`、`checkpoints/` 加 `.gitignore`(验证:`python -c "import tsmm"` 不报错;`pytest tests/` 可跑)
|
||||
- [ ] 1.2 属性词表与采样 `data/attributes.py`:定义变量名词表/单位/采样率档位,`sample_attributes(n_channels)` 返回结构化属性(验证:单测字段齐全、可复现)
|
||||
- [ ] 1.3 成分模型与时序合成 `data/synthesis.py`:`generate_series`(趋势+周期+基线+噪声)、`inject_anomaly`(尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移,返回逐点 labels+段元数据)、`couple_event`(t 处阶跃+事件文本)、`add_missing`(NaN 占位)(验证:给定 seed 确定;异常段与 labels 一致;事件处有阶跃)
|
||||
- [ ] 1.4 指令与回答生成 `data/instruct.py`:6 类指令模板(描述/异常/根因/预测/比较/事件关联)+ Evol-Instruct 演化,`build_instruction` 产 JSON 区间/数值/文本回答(验证:异常类 JSON 可 `json.loads` 且段与 labels 吻合)
|
||||
- [ ] 1.5 离线生成脚本 `scripts/gen_synthetic.py`:多进程产 `align.jsonl`(50万)/`sft.jsonl`(10万)/`eval_synth.jsonl`(2k held-out),支持 `--n/--out/--seed/--workers` + tqdm(验证:`--n 1000` 跑通,抽样 5 条 schema 合规)
|
||||
- [ ] 1.6 真实 benchmark 加载 `data/real_bench.py`:加载 SMD/MSL/SMAP/SWaT/PSM(至少 2 个),`load_windows(T=512, stride=256)` 滑窗+归一化+标签,异常段改写问答对存 `eval_real.jsonl`(验证:窗口形状 `[N,T,C]`、标签 `[N,T]`、问答非空)
|
||||
- [ ] 1.7 M1 出口验证:`gen_synthetic.py --n 1000` 产可视检合法 JSONL;`real_bench.py` 加载 ≥2 数据集;人工抽看 5 条合成样本确认成分/异常/事件正确
|
||||
|
||||
## 2. M2 · 模型可跑通
|
||||
|
||||
- [ ] 2.1 TS Encoder `model/ts_encoder.py`:`Patchify(patch=8, stride=4)` 通道独立切 patch 线性嵌入到 d=256;`TSEncoder(d=256, layers=2, heads=4)` 2 层 TF + 可学习位置编码;前向 `[B,T,C]`→`[B,n_patches,256]`(验证:输入 `[2,512,5]`→`[2,128,256]`,参数 ≈4M)
|
||||
- [ ] 2.2 Projector `model/projector.py`:`Linear(256→896)+LayerNorm`(验证:输出 `[B,128,896]` 对齐 Qwen2.5-0.5B hidden)
|
||||
- [ ] 2.3 多模态拼接 `model/multimodal.py`:Qwen tokenizer tokenize 文本部分,TS token 作 inputs_embeds 插入 `[属性][时间戳][TS tok][事件][问题]`,统一构造 inputs_embeds+attention_mask+labels(仅回答段非 -100)(验证:seq_len ≤1024,mask/labels 形状对)
|
||||
- [ ] 2.4 训练/推理封装 `model/wrapper.py`:`MultimodalTSModel` 组合 Encoder+Projector+LLM+LoRA 挂载开关,`forward` 返 loss、`generate` 返文本,支持 `freeze_llm`(阶段①)/`enable_lora(r=16)`(阶段②)(验证:单 batch forward 3060 不 OOM;generate 能出文本)
|
||||
- [ ] 2.5 Collator `data/collator.py`:JSONL→batch 张量,处理变长 C(padding+mask)与变长文本(padding+attention_mask)(验证:batch=4 张量形状一致无 NaN)
|
||||
- [ ] 2.6 M2 出口验证:单 batch 前向+反向在 3060 跑通,loss 有限且下降趋势,阶段①模式峰值显存 ~5GB
|
||||
|
||||
## 3. M3 · 阶段①对齐训练
|
||||
|
||||
- [ ] 3.1 损失函数 `train/losses.py`:`lm_loss`(仅回答段计 loss)、`contrastive_loss`(扰动时序→回答 embedding 变化,InfoNCE/扰动一致性),总 loss=`lm_loss+λ*contrastive_loss`(λ 默认 0.1)(验证:loss 标量可反传,对比损失对扰动敏感)
|
||||
- [ ] 3.2 阶段①训练脚本 `train/stage1.py`+`scripts/train_stage1.sh`:加载 `align.jsonl` 流式,`freeze_llm=True` 仅训 Encoder+Projector(AdamW, lr=1e-4),bs=8/grad_accum=4/ctx=512/BF16/梯度检查点,每 2000 step 存 ckpt + TensorBoard(验证:`--max_steps 100` 冒烟不 OOM、loss 下降、峰值显存 ≤6GB)
|
||||
- [ ] 3.3 TS-token 有效性检验:held-out 原时序 vs 扰动时序回答变化率 + 「必看时序」样本答对率对照纯 LLM(验证:扰动后变化率 >50%,必看时序答对率显著高于纯 LLM)
|
||||
- [ ] 3.4 M3 出口验证:阶段① ckpt 产出;扰动检验通过;峰值显存 ≤6GB(失败回查对比损失权重/数据质量)
|
||||
|
||||
## 4. M4 · 阶段②SFT
|
||||
|
||||
- [ ] 4.1 阶段②训练脚本 `train/stage2.py`+`scripts/train_stage2.sh`:加载阶段① ckpt,`enable_lora(r=16)` on q/v_proj 其余冻结,加载 `sft.jsonl`,bs=4/grad_accum=8/ctx=1024/BF16/梯度检查点,每 2000 step 存含 LoRA ckpt(验证:`--max_steps 100` 冒烟不 OOM、loss 下降、峰值显存 ≤11GB)
|
||||
- [ ] 4.2 指令遵循抽检:6 类任务各取 10 条 held-out 检查回答(异常类 JSON 可解析+段合理;解释类切题引用事件)(验证:6 类回答可用率 >70%,JSON 解析成功率 >80%)
|
||||
- [ ] 4.3 M4 出口验证:阶段② ckpt 产出;6 类任务抽检达标;峰值显存 ≤11GB(OOM 则降 bs=2/grad_accum=16、`adamw_8bit`+CPU offload、ctx 降到 768)
|
||||
|
||||
## 5. M5 · 完整评测
|
||||
|
||||
- [ ] 5.1 回答解析 `eval/parse_answer.py`:文本回答→JSON 异常段→逐点分数 `[T]`,失败→全 0+失败标记(验证:多格式可解析、失败有兜底)
|
||||
- [ ] 5.2 异常检测指标 `eval/ts_metrics.py`:`tsb_uad` 算 VUS-PR(主),自实现 Affiliation-F1(多 λ)/AUC-PR/Point-F1(无PA),PA-F1 单独对照(验证:已知段算出合理值;trivial 全报异常 VUS-PR 不虚高)
|
||||
- [ ] 5.3 问答评测 `eval/qa_judge.py`:规则解析轨(JSON/数值容差→准确率)+ LLM-judge 轨(GPT-4o 打 0-5 分),不一致样本导出抽检(验证:对 eval 集产出 6 类任务的 {规则准确率,judge 均分,解析成功率})
|
||||
- [ ] 5.4 对照基线 `eval/baselines.py`:纯 LLM 数值喂文本 / Time-LLM 风格重映射 / ChatTS(若可复现) / Trivial(Random/Constant/全报异常),全走同一套 parse+metrics(验证:4 类基线产出同口径指标表)
|
||||
- [ ] 5.5 评测脚本与报告 `scripts/run_eval.sh`:跑 `eval_synth.jsonl`+`eval_real.jsonl`,产 `reports/eval-YYYYMMDD.md`(含每数据集×每任务全部必报指标、标注是否用 PA、含 trivial 对照)(验证:一键产出满足设计规格 §5.4 必报清单的完整报告)
|
||||
- [ ] 5.6 M5 出口验证:报告满足设计规格 §6.5 成功标准——真实 benchmark VUS-PR 显著优于纯 LLM 基线;时序消融后指标明显下降;问答均分超基线;评测可复现含 trivial
|
||||
```
|
||||
|
||||
## openspec/changes/ts-as-modality/specs/ts-evaluation/spec.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/specs/ts-evaluation/spec.md
|
||||
- Lines: 1-61
|
||||
- SHA256: 1c986559a6b44900bff452e4cbbb0272c1ee321de2fddacedc6e096c4e5381fb
|
||||
|
||||
```md
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 回答解析为逐点分数
|
||||
|
||||
系统 SHALL 从模型自然语言回答中提取 JSON 异常段并生成逐点分数(段内 1.0,段外 0.0),解析失败时回退为全 0(计为漏报)并记录失败标记。
|
||||
|
||||
#### Scenario: 多格式可解析
|
||||
- **WHEN** 输入含噪声/嵌套的多种回答格式
|
||||
- **THEN** 能正确解析出异常段并生成逐点分数 `[T]`
|
||||
|
||||
#### Scenario: 解析失败有兜底
|
||||
- **WHEN** 回答无法解析
|
||||
- **THEN** 分数全 0 并记录失败标记(不计为成功)
|
||||
|
||||
### Requirement: 阈值无关的异常检测指标
|
||||
|
||||
系统 SHALL 以 VUS-PR 为异常检测主指标,并辅以 Affiliation-F1(λ=0.1/0.5/1.0)、AUC-PR、Point-F1(无 PA);PA-F1 仅作对照、不得作为主指标。
|
||||
|
||||
#### Scenario: trivial 基线不虚高
|
||||
- **WHEN** 对「全报异常」trivial 基线计算 VUS-PR
|
||||
- **THEN** VUS-PR 不虚高(避免评估作弊)
|
||||
|
||||
#### Scenario: 对已知段算出合理值
|
||||
- **WHEN** 对已知异常段计算指标
|
||||
- **THEN** VUS-PR/Aff-F1/AUC-PR/Point-F1 均落在合理区间
|
||||
|
||||
### Requirement: 问答评测双轨
|
||||
|
||||
系统 SHALL 提供规则解析轨(JSON/数值容差比对,产准确率)与 LLM-judge 轨(对 `问题,时序摘要,参考答案,模型答案` 打 0-5 分),并对两轨不一致样本导出供人工抽检。
|
||||
|
||||
#### Scenario: 产出 6 类任务评测结果
|
||||
- **WHEN** 对评测集运行问答评测
|
||||
- **THEN** 对 6 类任务各产出 `{规则准确率, judge 均分, 解析成功率}`
|
||||
|
||||
### Requirement: 同口径对照基线
|
||||
|
||||
系统 SHALL 提供 4 类同口径基线——纯 LLM 数值喂文本、Time-LLM 风格重映射、ChatTS(若不可复现则标注)、Trivial(Random/Constant/全报异常)——且全部走同一套解析+指标脚本。
|
||||
|
||||
#### Scenario: 4 类基线产出同口径指标
|
||||
- **WHEN** 运行基线评测
|
||||
- **THEN** 4 类基线均在同一套 `parse_answer`+`ts_metrics` 下产出指标表
|
||||
|
||||
### Requirement: 可复现评测报告
|
||||
|
||||
系统 SHALL 提供一键评测脚本,产出 markdown 报告,覆盖每数据集×每任务的 VUS-PR/Aff-F1/AUC-PR/Point-F1/PA-F1(对照)/问答分/解析成功率/消融/基线对比,并明确标注是否使用 PA、含 trivial 对照。
|
||||
|
||||
#### Scenario: 一键产出完整报告
|
||||
- **WHEN** 运行 `run_eval.sh`
|
||||
- **THEN** 产出满足设计规格 §5.4 必报清单的完整 markdown 报告
|
||||
|
||||
### Requirement: 模态消融与泛化验证
|
||||
|
||||
系统 SHALL 支持模态消融(去掉事件/属性/时序)与跨数据集泛化验证(如 SMD→MSL/SWaT),以证明时序模态确有贡献并暴露合成→真实差距。
|
||||
|
||||
#### Scenario: 时序消融指标下降
|
||||
- **WHEN** 去掉时序模态后评测
|
||||
- **THEN** 关键指标(VUS-PR/问答分)明显低于完整模型,证明时序模态有贡献
|
||||
|
||||
#### Scenario: 真实 benchmark 显著优于纯 LLM 基线
|
||||
- **WHEN** 在真实 benchmark 上对比完整模型与纯 LLM 数值喂文本基线
|
||||
- **THEN** VUS-PR 显著优于纯 LLM 基线
|
||||
```
|
||||
|
||||
## openspec/changes/ts-as-modality/specs/ts-multimodal-model/spec.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/specs/ts-multimodal-model/spec.md
|
||||
- Lines: 1-73
|
||||
- SHA256: f40631b2e8dac3772f6081623d2175460ca5355a8818d6cb3c28a94f148d56a3
|
||||
|
||||
```md
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: TS Encoder 把时序编码为 patch 表示
|
||||
|
||||
系统 SHALL 通过通道独立的 Patchify(P=8, stride=4)将多变量时序切分为重叠 patch,并经 2 层 Transformer 编码器(d=256, 4 头)映射为时序 token 序列。
|
||||
|
||||
#### Scenario: 形状正确
|
||||
- **WHEN** 输入形状 `[B, T=512, C=5]`
|
||||
- **THEN** 输出形状 `[B, 128, 256]`,且 TS Encoder 参数量约 4M
|
||||
|
||||
#### Scenario: 通道独立
|
||||
- **WHEN** 通道数 C 变化(如 C=3 与 C=12)
|
||||
- **THEN** 编码器仍正常工作(通道独立 patchify,不因 C 增大失配)
|
||||
|
||||
### Requirement: Projector 映射到 LLM 隐藏维
|
||||
|
||||
系统 SHALL 提供线性投影层(256→896)+ LayerNorm,将 TS 表示映射到 Qwen2.5-0.5B 的隐藏维(896),作为可学习 soft token。
|
||||
|
||||
#### Scenario: 投影对齐 LLM hidden
|
||||
- **WHEN** TS Encoder 输出 `[B, 128, 256]`
|
||||
- **THEN** Projector 输出 `[B, 128, 896]`,与 LLM 隐藏维一致
|
||||
|
||||
### Requirement: 多模态拼接注入 LLM
|
||||
|
||||
系统 SHALL 按 `[属性][时间戳][TS token][事件][问题]` 顺序组装文本 token 与 TS token,统一构造 `inputs_embeds`(文本走 `get_input_embeddings()`,TS 走 Projector 输出)+ `attention_mask` + `labels`(仅回答段非 -100),并约束总长度。
|
||||
|
||||
#### Scenario: 拼接长度受限
|
||||
- **WHEN** 组装一个样本
|
||||
- **THEN** 拼接后序列长度 ≤1024 token
|
||||
|
||||
#### Scenario: 回答段 mask 正确
|
||||
- **WHEN** 构造 labels
|
||||
- **THEN** prompt 段(属性/时序/事件/问题)token 的 label 为 -100,仅回答段非 -100
|
||||
|
||||
### Requirement: 训练/推理统一封装
|
||||
|
||||
系统 SHALL 提供统一封装,组合 TS Encoder + Projector + LLM + 可选 LoRA,`forward(batch)` 返回 loss、`generate(batch)` 返回文本,并支持阶段①(冻结 LLM)与阶段②(LoRA r=16 on q/v_proj)两种模式。
|
||||
|
||||
#### Scenario: 单卡前向反向不 OOM
|
||||
- **WHEN** 在 3060 12GB 上以阶段①模式跑单 batch 前向+反向
|
||||
- **THEN** 不 OOM,loss 为有限值
|
||||
|
||||
#### Scenario: 可生成文本
|
||||
- **WHEN** 调用 `generate(batch)`
|
||||
- **THEN** 返回文本(训练初期允许内容无意义,但流程通)
|
||||
|
||||
### Requirement: 阶段①对齐预训练
|
||||
|
||||
系统 SHALL 支持阶段①训练:冻结 LLM 主体,仅训 TS Encoder + Projector(AdamW),上下文 ≤512、BF16、梯度检查点,并对回答段计 LM loss,叠加对比损失(扰动时序→回答应变)以防止 LLM 忽略 TS token。
|
||||
|
||||
#### Scenario: 冒烟跑通且省显存
|
||||
- **WHEN** 以 `--max_steps 100` 冒烟训练
|
||||
- **THEN** 不 OOM,loss 呈下降趋势,峰值显存 ≤6GB
|
||||
|
||||
#### Scenario: TS token 被有效利用
|
||||
- **WHEN** 训练后对 held-out 样本比较原时序与扰动时序的回答
|
||||
- **THEN** 扰动后回答变化率 >50%
|
||||
|
||||
### Requirement: 阶段②指令微调 SFT
|
||||
|
||||
系统 SHALL 支持阶段②训练:加载阶段① checkpoint,叠加 LoRA r=16(q/v_proj)、LLM 其余冻结,上下文 ≤1024、BF16、梯度检查点,对回答段做 SFT LM loss。
|
||||
|
||||
#### Scenario: 冒烟跑通且压在显存内
|
||||
- **WHEN** 以 `--max_steps 100` 冒烟训练
|
||||
- **THEN** 不 OOM,loss 下降,峰值显存 ≤11GB
|
||||
|
||||
### Requirement: 分阶段 checkpoint 与断点续训
|
||||
|
||||
系统 SHALL 为每个阶段独立存放 checkpoint(阶段① = Encoder+Projector;阶段②在此之上叠加 LoRA),支持断点续训(每 2000 step 存 ckpt,JSONL 流式加载支持任意 step 续)。
|
||||
|
||||
#### Scenario: 分阶段互不污染
|
||||
- **WHEN** 加载阶段② checkpoint
|
||||
- **THEN** 其依赖的阶段① Encoder+Projector 权重与阶段② LoRA 适配器可分别回滚,互不污染
|
||||
```
|
||||
|
||||
## openspec/changes/ts-as-modality/specs/ts-synthesis/spec.md
|
||||
|
||||
- Source: openspec/changes/ts-as-modality/specs/ts-synthesis/spec.md
|
||||
- Lines: 1-77
|
||||
- SHA256: 330043d178e344f1f1e87d1262f25ed33b2216eb6e16f2658d4f29a779d8b60b
|
||||
|
||||
```md
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 可复现的合成时序生成
|
||||
|
||||
系统 SHALL 提供 CPU 离线合成数据管线,通过可配置成分模型叠加生成多变量时序,且在给定随机种子下输出完全确定、可复现。
|
||||
|
||||
#### Scenario: 给定种子输出确定
|
||||
- **WHEN** 使用相同 seed 调用 `generate_series(T, C, seed)` 两次
|
||||
- **THEN** 两次输出的时序数组逐点相等
|
||||
|
||||
#### Scenario: 成分叠加覆盖典型形态
|
||||
- **WHEN** 生成一条时序
|
||||
- **THEN** 该时序由趋势/周期/基线/噪声(含高斯与重尾 Student-t)成分叠加而成,且各成分参数被记录为元数据
|
||||
|
||||
### Requirement: 异常注入与精确标签
|
||||
|
||||
系统 SHALL 支持向合成时序注入多类异常,并把异常段位置与逐点标签作为 ground-truth 自动记录,标签与异常位置一致。
|
||||
|
||||
#### Scenario: 注入异常并记录逐点标签
|
||||
- **WHEN** 调用 `inject_anomaly(series, types)` 注入尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移中的任一类
|
||||
- **THEN** 返回 `(series, labels)`,其中 labels 为逐点 0/1,且 labels 中值为 1 的点与实际异常区间一致
|
||||
|
||||
#### Scenario: 异常稀有性兜底
|
||||
- **WHEN** 生成用于训练的样本
|
||||
- **THEN** 每条样本至少包含 1 类异常,保证异常类指令任务有正样本
|
||||
|
||||
### Requirement: 事件耦合
|
||||
|
||||
系统 SHALL 支持在指定时间点注入事件相关的阶跃变化,并生成对应的事件文本描述,以支撑时序+事件联合推理。
|
||||
|
||||
#### Scenario: 事件注入产生阶跃
|
||||
- **WHEN** 调用 `couple_event(series, t, kind)` 在时间 t 注入事件
|
||||
- **THEN** 时序在 t 处出现阶跃变化,并返回该事件的文本描述
|
||||
|
||||
### Requirement: 缺失与不规则采样模拟
|
||||
|
||||
系统 SHALL 支持随机丢弃部分时序点(用 NaN 占位),以模拟真实采集缺陷。
|
||||
|
||||
#### Scenario: 按比例丢弃点
|
||||
- **WHEN** 调用 `add_missing(series, rate=0.05~0.10)`
|
||||
- **THEN** 约 5-10% 的点被置为 NaN 占位
|
||||
|
||||
### Requirement: 属性词表采样
|
||||
|
||||
系统 SHALL 提供变量名词表(CPU/内存/流量/延迟/温度/请求量等)、单位与采样率档位,并按通道数采样返回结构化属性。
|
||||
|
||||
#### Scenario: 采样属性字段齐全
|
||||
- **WHEN** 调用 `sample_attributes(n_channels)`
|
||||
- **THEN** 返回长度为 n_channels 的列表,每项含 `name`、`unit`、`freq` 字段,且给定 seed 可复现
|
||||
|
||||
### Requirement: 多类指令与回答生成
|
||||
|
||||
系统 SHALL 支持 6 类指令任务(描述/统计、异常检测、根因/解释、预测、比较、事件关联),为每类生成指令,并产出可结构化解析的回答(异常类含 JSON 区间,统计类含数值,解释类含文本)。
|
||||
|
||||
#### Scenario: 异常类回答可被解析
|
||||
- **WHEN** 生成异常检测类的指令与回答
|
||||
- **THEN** 回答中的 JSON 可被 `json.loads` 解析,且其异常段与 labels 吻合
|
||||
|
||||
#### Scenario: 覆盖全部 6 类
|
||||
- **WHEN** 运行指令生成
|
||||
- **THEN** 6 类任务每类至少各产 1 条样本
|
||||
|
||||
### Requirement: 离线批量生成 JSONL
|
||||
|
||||
系统 SHALL 提供离线脚本多进程生成 JSONL 数据集,每条记录含 `series`/`attributes`/`timestamps`/`events`/`instruction`/`answer`/`labels`,并支持条数、输出路径、种子、并发数参数。
|
||||
|
||||
#### Scenario: 小规模生成产出合法 schema
|
||||
- **WHEN** 运行 `gen_synthetic.py --n 1000`
|
||||
- **THEN** 抽样 5 条每条均含上述 7 个字段,schema 合规
|
||||
|
||||
### Requirement: 真实 benchmark 加载与问答改写
|
||||
|
||||
系统 SHALL 能加载真实多变量时序 benchmark 窗口(至少 SWaT 与 MSL/MSL 系列中的 2 个),做滑窗+归一化+异常标签对齐,并把异常段改写为问答对(仅评测用,不进训练)。
|
||||
|
||||
#### Scenario: 加载并滑窗
|
||||
- **WHEN** 调用 `load_windows(name, T=512, stride=256)`
|
||||
- **THEN** 返回窗口形状 `[N, T, C]` 与标签形状 `[N, T]`,问答对非空
|
||||
```
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-06-29
|
||||
@@ -0,0 +1,88 @@
|
||||
## Context
|
||||
|
||||
本 change 在**单张 3060 12GB 消费级显卡**上做一个可复现的实验性落地:把**多变量时序视为独立模态**,与文本/事件模态联合注入小型 LLM(Qwen2.5-0.5B-Instruct),端到端任务是**时序问答与推理**(ChatTS 路线)。
|
||||
|
||||
背景与约束来自 `MTSAD-技术深度调研报告.md` 与 `docs/superpowers/specs/2026-06-29-ts-as-modality-design.md`(已通过设计评审)。核心约束:
|
||||
|
||||
- **算力**:单卡 12GB → 骨干 ≤0.5B、依赖 LoRA/QLoRA + 短上下文 + 小批量 + 梯度检查点
|
||||
- **数据**:合成数据为主(CPU 离线生成)→ 评测锚定真实 benchmark,防合成过拟合
|
||||
- **目标**:不追学术 SOTA,追「12GB 跑通、可复现、时序模态确有增益」的可验证结论
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 全流程单卡 3060 12GB 跑通,阶段②峰值显存 ≤11GB
|
||||
- TS Encoder + Projector 把时序编码为独立 soft token,使 LLM「能读懂」时序
|
||||
- 时序模态带来可量化增益:真实 benchmark VUS-PR 显著优于纯 LLM 数值喂文本基线;时序消融后指标明显下降
|
||||
- 6 类问答任务(描述/异常/根因/预测/比较/事件关联)LLM-judge 均分超纯 LLM 基线
|
||||
- 评测可复现:含 trivial 基线对照、标注是否用 PA、严守 MTSAD 报告评估纪律
|
||||
|
||||
**Non-Goals:**
|
||||
- ❌ 不从零预训练 LLM(成本不允许,且非本实验目的)
|
||||
- ❌ 不做多卡分布式训练(单卡约束)
|
||||
- ❌ 不追求学术 SOTA 排名
|
||||
- ❌ 不做端侧部署优化(先验证方法)
|
||||
- ❌ DPO 首版不做(M5 后视效果再决定)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 决策 1:采用 Patch-Project + 轻量编码器,而非时序 Tokenization 或 Reprogramming
|
||||
|
||||
时序切 patch(P=8, stride=4,通道独立)→ 2 层 Transformer 编码器(d=256, 4 头, ~4M)→ 线性投影(256→896)成独立 TS token,作为可学习 soft token 注入 LLM。
|
||||
|
||||
**对比的备选方案:**
|
||||
|
||||
| 方案 | 含义 | 取舍 |
|
||||
|------|------|------|
|
||||
| **A(选用)Patch-Project + 轻量编码器** | patch→小编码器→线性投影成独立 TS token | 真正的"时序作为模态";12GB 可训;patch 捕捉局部结构、变长友好。代价:需训编码器+投影层(已在显存预算内) |
|
||||
| B 时序 Tokenization(Chronos 风格) | 数值量化成离散 token、扩展词表 | 最"时序即语言",但量化丢精度、异常细节易损;逐点 token 序列长,12GB 上下文吃紧。放弃 |
|
||||
| C Reprogramming(Time-LLM 风格) | 冻结 LLM 用文本原型重映射 | 参数最省,但受限于已有文本嵌入流形、表达力弱,时序算不上"真新模态",复杂推理/事件联合弱。放弃 |
|
||||
|
||||
### 决策 2:骨干选 Qwen2.5-0.5B-Instruct
|
||||
|
||||
0.5B 中英均衡、有现成 Instruct 版、社区生态成熟;BF16 约 1GB,12GB 余量充足(hidden=896)。
|
||||
|
||||
### 决策 3:两阶段训练,阶段①冻结 LLM
|
||||
|
||||
- **阶段① 对齐预训练**:冻结 LLM,仅训 TS Encoder + Projector(~4.2M 全参)→ 不存 LLM 优化器状态/梯度,是 12GB 可行的关键省显存技巧
|
||||
- **阶段② SFT**:在此之上叠加 LoRA r=16(q/v_proj,~2-3M),LLM 其余冻结 + 梯度检查点
|
||||
|
||||
分阶段 checkpoint 互不污染、可回滚。损失仅对回答段 token 计 LM loss;阶段①叠加对比损失(扰动时序→回答应变)防止 LLM 忽略 TS token。
|
||||
|
||||
### 决策 4:输入拼接顺序 `[属性][时间戳][TS token][事件][问题]`
|
||||
|
||||
属性先给语义,时序居中,事件定位在对应时间,问题在末尾便于回答。
|
||||
|
||||
### 决策 5:合成数据为主,真实 benchmark 仅用于评测锚定
|
||||
|
||||
合成管线全 CPU 离线,成分参数随机化;**核心红利**:异常段、事件时间戳、各成分参数全部作为 ground-truth 自动记录——免费且精确的标签。评测锚定 SMD/MSL/SMAP/SWaT/PSM 真实分布,避免「合成上 SOTA、真实上崩盘」。
|
||||
|
||||
### 决策 6:评测指标以 VUS-PR 为主,严守 MTSAD 报告纪律
|
||||
|
||||
- 主指标 **VUS-PR**(阈值无关);辅 Affiliation-F1(多 λ)、AUC-PR、Point-F1(无 PA)
|
||||
- **PA-F1 仅作对照、不得作主指标**(防虚高)
|
||||
- 问答用 LLM-judge + 规则解析双轨
|
||||
- 自然语言回答→约束 JSON 区间→逐点分数,便于数值化评测
|
||||
|
||||
### 决策 7:4 类同口径基线
|
||||
|
||||
纯 LLM 数值喂文本(检验 TS 模态是否真有增益)、Time-LLM 风格重映射、ChatTS(若可复现)、Trivial(Random/Constant/全报异常)。全部走同一套解析+指标脚本。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [12GB 阶段②仍 OOM] → 降批量/上下文、开 CPU offload 优化器、`adamw_8bit`、退回阶段①-only 报告
|
||||
- [合成→真实泛化差距大(高风险)] → 阶段②掺真实 benchmark 改写样本;评测以真实 benchmark 为准
|
||||
- [LLM 忽略 TS token] → 对比损失 + "必看时序"样本 + 消融实验定位
|
||||
- [回答 JSON 解析失败率高] → 训练强化格式约束 + 解析兜底(失败→全 0 计漏报)+ 单独报解析成功率
|
||||
- [GPT-4o judge 成本] → 仅评测 2k 样本调用;可换开源 judge 做 sanity
|
||||
- [TS Encoder 过拟合合成分布] → 成分参数随机化 + 多套合成配置 + 阶段②引入真实改写样本
|
||||
|
||||
## Open Questions
|
||||
|
||||
- TS Encoder 层数/d 是否需小规模 sweep(2 层是否够)
|
||||
- Patch P=8/stride=4 是否最优,是否需对比 P=16
|
||||
- 对比损失具体形式(InfoNCE vs 扰动一致性)与权重 λ
|
||||
- DPO 是否纳入首版(建议首版先不做,M5 后视效果决定)
|
||||
- 真实 benchmark 改写问答的数量与质量校验流程
|
||||
|
||||
> 详细行为需求见 `specs/ts-synthesis/`、`specs/ts-multimodal-model/`、`specs/ts-evaluation/`;任务拆解见 `tasks.md`(M1→M5)。
|
||||
@@ -0,0 +1,33 @@
|
||||
## Why
|
||||
|
||||
当前 AIOps 场景下,多变量时序的异常检测与解释仍依赖专用模型,缺乏「以自然语言对时序提问、做根因/事件关联推理」的统一能力。基于 `MTSAD-技术深度调研报告.md`,沿用 ChatTS「时序作为新模态」路线,我们希望在**单张 3060 12GB 消费级显卡**上做一个可复现的实验性落地,验证「把多变量时序视为独立模态、与文本/事件模态联合注入小型 LLM」这一方法在算力受限条件下是否切实可行、且「时序模态」是否真带来可量化的增益。现在做是因为:0.5B 级开源 LLM 与 PEFT/LoRA 工具链已足够成熟,使该实验在消费级硬件上首次成为可能。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **新增**:CPU 离线合成数据管线(成分模型 + 异常注入 + 事件耦合 + Evol-Instruct 指令/回答生成),产出对齐预训练与 SFT 用的 JSONL
|
||||
- **新增**:真实 benchmark(SMD/MSL/SMAP/SWaT/PSM)窗口加载与「异常段→问答对」改写(仅评测用,不进训练)
|
||||
- **新增**:TS Encoder(Patchify + 2 层 Transformer)+ Projector(Linear→LLM hidden),把时序编码为独立 soft token
|
||||
- **新增**:多模态拼接器,按 `[属性][时间戳][TS token][事件][问题]` 顺序组装文本 token 与 TS token 注入 LLM
|
||||
- **新增**:两阶段训练流程 —— 阶段①冻结 LLM 训 Encoder+Projector(对齐预训练);阶段②叠加 LoRA(r=16) 做指令微调
|
||||
- **新增**:评测套件 —— 文本回答→JSON 区间→逐点分数解析;VUS-PR(主)/Affiliation-F1/AUC-PR/Point-F1(无PA);LLM-judge + 规则解析双轨
|
||||
- **新增**:4 类同口径对照基线(纯 LLM 数值喂文本 / Time-LLM 风格重映射 / ChatTS(若可复现) / Trivial)
|
||||
- 骨干选用 **Qwen2.5-0.5B-Instruct**,BF16 + LoRA + 梯度检查点,目标阶段②峰值显存 ≤11GB
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `ts-synthesis`: CPU 离线合成数据管线——成分模型(趋势/周期/基线/噪声)、异常注入(尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移)、事件耦合、缺失/不规则模拟、属性词表采样,以及 Evol-Instruct 多轮指令与回答生成;附带真实 benchmark 加载与问答改写
|
||||
- `ts-multimodal-model`: 时序作为模态的多模态模型——TS Encoder + Projector + 多模态拼接(TS token 与文本/事件 token 联合注入 LLM),含阶段①对齐预训练与阶段②LoRA SFT 的训练/推理统一封装
|
||||
- `ts-evaluation`: 时序问答与异常检测评测套件——回答解析(文本→JSON 区间→逐点分数)、阈值无关指标(VUS-PR 主/Affiliation-F1/AUC-PR/Point-F1 无 PA)、LLM-judge + 规则双轨、4 类同口径基线对照、可复现评测报告
|
||||
|
||||
### Modified Capabilities
|
||||
<!-- 无已存在 capability 的需求变更(本项目 specs/ 当前为空)。 -->
|
||||
|
||||
## Impact
|
||||
|
||||
- **新增代码**:独立 Python 项目 `ts-as-modality/`(`pyproject.toml` + `src/tsmm/{data,model,train,eval,utils}` + `scripts/` + `tests/` + `configs/`),与当前 spec/docs 工作区并列
|
||||
- **依赖**:torch、transformers、peft、accelerate、datasets、numpy、tqdm、pyyaml、pytest;评测依赖 `tsb_uad`(VUS-PR);LLM-judge 评测时调用 OpenAI/GPT-4o API
|
||||
- **模型资产**:Qwen2.5-0.5B-Instruct 骨干(外部下载);阶段①/② checkpoint 与合成数据产物体积较大,需 git-ignore(`data/`、`checkpoints/`)
|
||||
- **算力**:单张 3060 12GB;阶段①预估峰值 ~4-5GB,阶段②预估峰值 ~9-10GB;CPU 多进程用于离线合成
|
||||
- **存储**:合成数据约 2-3GB(流式加载),checkpoint 分阶段独立存放
|
||||
- **无 BREAKING 变更**:纯新增独立实验项目,不触碰现有任何代码/接口
|
||||
@@ -0,0 +1,61 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 回答解析为逐点分数
|
||||
|
||||
系统 SHALL 从模型自然语言回答中提取 JSON 异常段并生成逐点分数(段内 1.0,段外 0.0),解析失败时回退为全 0(计为漏报)并记录失败标记。
|
||||
|
||||
#### Scenario: 多格式可解析
|
||||
- **WHEN** 输入含噪声/嵌套的多种回答格式
|
||||
- **THEN** 能正确解析出异常段并生成逐点分数 `[T]`
|
||||
|
||||
#### Scenario: 解析失败有兜底
|
||||
- **WHEN** 回答无法解析
|
||||
- **THEN** 分数全 0 并记录失败标记(不计为成功)
|
||||
|
||||
### Requirement: 阈值无关的异常检测指标
|
||||
|
||||
系统 SHALL 以 VUS-PR 为异常检测主指标,并辅以 Affiliation-F1(λ=0.1/0.5/1.0)、AUC-PR、Point-F1(无 PA);PA-F1 仅作对照、不得作为主指标。
|
||||
|
||||
#### Scenario: trivial 基线不虚高
|
||||
- **WHEN** 对「全报异常」trivial 基线计算 VUS-PR
|
||||
- **THEN** VUS-PR 不虚高(避免评估作弊)
|
||||
|
||||
#### Scenario: 对已知段算出合理值
|
||||
- **WHEN** 对已知异常段计算指标
|
||||
- **THEN** VUS-PR/Aff-F1/AUC-PR/Point-F1 均落在合理区间
|
||||
|
||||
### Requirement: 问答评测双轨
|
||||
|
||||
系统 SHALL 提供规则解析轨(JSON/数值容差比对,产准确率)与 LLM-judge 轨(对 `问题,时序摘要,参考答案,模型答案` 打 0-5 分),并对两轨不一致样本导出供人工抽检。
|
||||
|
||||
#### Scenario: 产出 6 类任务评测结果
|
||||
- **WHEN** 对评测集运行问答评测
|
||||
- **THEN** 对 6 类任务各产出 `{规则准确率, judge 均分, 解析成功率}`
|
||||
|
||||
### Requirement: 同口径对照基线
|
||||
|
||||
系统 SHALL 提供 4 类同口径基线——纯 LLM 数值喂文本、Time-LLM 风格重映射、ChatTS(若不可复现则标注)、Trivial(Random/Constant/全报异常)——且全部走同一套解析+指标脚本。
|
||||
|
||||
#### Scenario: 4 类基线产出同口径指标
|
||||
- **WHEN** 运行基线评测
|
||||
- **THEN** 4 类基线均在同一套 `parse_answer`+`ts_metrics` 下产出指标表
|
||||
|
||||
### Requirement: 可复现评测报告
|
||||
|
||||
系统 SHALL 提供一键评测脚本,产出 markdown 报告,覆盖每数据集×每任务的 VUS-PR/Aff-F1/AUC-PR/Point-F1/PA-F1(对照)/问答分/解析成功率/消融/基线对比,并明确标注是否使用 PA、含 trivial 对照。
|
||||
|
||||
#### Scenario: 一键产出完整报告
|
||||
- **WHEN** 运行 `run_eval.sh`
|
||||
- **THEN** 产出满足设计规格 §5.4 必报清单的完整 markdown 报告
|
||||
|
||||
### Requirement: 模态消融与泛化验证
|
||||
|
||||
系统 SHALL 支持模态消融(去掉事件/属性/时序)与跨数据集泛化验证(如 SMD→MSL/SWaT),以证明时序模态确有贡献并暴露合成→真实差距。
|
||||
|
||||
#### Scenario: 时序消融指标下降
|
||||
- **WHEN** 去掉时序模态后评测
|
||||
- **THEN** 关键指标(VUS-PR/问答分)明显低于完整模型,证明时序模态有贡献
|
||||
|
||||
#### Scenario: 真实 benchmark 显著优于纯 LLM 基线
|
||||
- **WHEN** 在真实 benchmark 上对比完整模型与纯 LLM 数值喂文本基线
|
||||
- **THEN** VUS-PR 显著优于纯 LLM 基线
|
||||
@@ -0,0 +1,73 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: TS Encoder 把时序编码为 patch 表示
|
||||
|
||||
系统 SHALL 通过通道独立的 Patchify(P=8, stride=4)将多变量时序切分为重叠 patch,并经 2 层 Transformer 编码器(d=256, 4 头)映射为时序 token 序列。
|
||||
|
||||
#### Scenario: 形状正确
|
||||
- **WHEN** 输入形状 `[B, T=512, C=5]`
|
||||
- **THEN** 输出形状 `[B, 128, 256]`,且 TS Encoder 参数量约 4M
|
||||
|
||||
#### Scenario: 通道独立
|
||||
- **WHEN** 通道数 C 变化(如 C=3 与 C=12)
|
||||
- **THEN** 编码器仍正常工作(通道独立 patchify,不因 C 增大失配)
|
||||
|
||||
### Requirement: Projector 映射到 LLM 隐藏维
|
||||
|
||||
系统 SHALL 提供线性投影层(256→896)+ LayerNorm,将 TS 表示映射到 Qwen2.5-0.5B 的隐藏维(896),作为可学习 soft token。
|
||||
|
||||
#### Scenario: 投影对齐 LLM hidden
|
||||
- **WHEN** TS Encoder 输出 `[B, 128, 256]`
|
||||
- **THEN** Projector 输出 `[B, 128, 896]`,与 LLM 隐藏维一致
|
||||
|
||||
### Requirement: 多模态拼接注入 LLM
|
||||
|
||||
系统 SHALL 按 `[属性][时间戳][TS token][事件][问题]` 顺序组装文本 token 与 TS token,统一构造 `inputs_embeds`(文本走 `get_input_embeddings()`,TS 走 Projector 输出)+ `attention_mask` + `labels`(仅回答段非 -100),并约束总长度。
|
||||
|
||||
#### Scenario: 拼接长度受限
|
||||
- **WHEN** 组装一个样本
|
||||
- **THEN** 拼接后序列长度 ≤1024 token
|
||||
|
||||
#### Scenario: 回答段 mask 正确
|
||||
- **WHEN** 构造 labels
|
||||
- **THEN** prompt 段(属性/时序/事件/问题)token 的 label 为 -100,仅回答段非 -100
|
||||
|
||||
### Requirement: 训练/推理统一封装
|
||||
|
||||
系统 SHALL 提供统一封装,组合 TS Encoder + Projector + LLM + 可选 LoRA,`forward(batch)` 返回 loss、`generate(batch)` 返回文本,并支持阶段①(冻结 LLM)与阶段②(LoRA r=16 on q/v_proj)两种模式。
|
||||
|
||||
#### Scenario: 单卡前向反向不 OOM
|
||||
- **WHEN** 在 3060 12GB 上以阶段①模式跑单 batch 前向+反向
|
||||
- **THEN** 不 OOM,loss 为有限值
|
||||
|
||||
#### Scenario: 可生成文本
|
||||
- **WHEN** 调用 `generate(batch)`
|
||||
- **THEN** 返回文本(训练初期允许内容无意义,但流程通)
|
||||
|
||||
### Requirement: 阶段①对齐预训练
|
||||
|
||||
系统 SHALL 支持阶段①训练:冻结 LLM 主体,仅训 TS Encoder + Projector(AdamW),上下文 ≤512、BF16、梯度检查点,并对回答段计 LM loss,叠加对比损失(扰动时序→回答应变)以防止 LLM 忽略 TS token。
|
||||
|
||||
#### Scenario: 冒烟跑通且省显存
|
||||
- **WHEN** 以 `--max_steps 100` 冒烟训练
|
||||
- **THEN** 不 OOM,loss 呈下降趋势,峰值显存 ≤6GB
|
||||
|
||||
#### Scenario: TS token 被有效利用
|
||||
- **WHEN** 训练后对 held-out 样本比较原时序与扰动时序的回答
|
||||
- **THEN** 扰动后回答变化率 >50%
|
||||
|
||||
### Requirement: 阶段②指令微调 SFT
|
||||
|
||||
系统 SHALL 支持阶段②训练:加载阶段① checkpoint,叠加 LoRA r=16(q/v_proj)、LLM 其余冻结,上下文 ≤1024、BF16、梯度检查点,对回答段做 SFT LM loss。
|
||||
|
||||
#### Scenario: 冒烟跑通且压在显存内
|
||||
- **WHEN** 以 `--max_steps 100` 冒烟训练
|
||||
- **THEN** 不 OOM,loss 下降,峰值显存 ≤11GB
|
||||
|
||||
### Requirement: 分阶段 checkpoint 与断点续训
|
||||
|
||||
系统 SHALL 为每个阶段独立存放 checkpoint(阶段① = Encoder+Projector;阶段②在此之上叠加 LoRA),支持断点续训(每 2000 step 存 ckpt,JSONL 流式加载支持任意 step 续)。
|
||||
|
||||
#### Scenario: 分阶段互不污染
|
||||
- **WHEN** 加载阶段② checkpoint
|
||||
- **THEN** 其依赖的阶段① Encoder+Projector 权重与阶段② LoRA 适配器可分别回滚,互不污染
|
||||
@@ -0,0 +1,77 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 可复现的合成时序生成
|
||||
|
||||
系统 SHALL 提供 CPU 离线合成数据管线,通过可配置成分模型叠加生成多变量时序,且在给定随机种子下输出完全确定、可复现。
|
||||
|
||||
#### Scenario: 给定种子输出确定
|
||||
- **WHEN** 使用相同 seed 调用 `generate_series(T, C, seed)` 两次
|
||||
- **THEN** 两次输出的时序数组逐点相等
|
||||
|
||||
#### Scenario: 成分叠加覆盖典型形态
|
||||
- **WHEN** 生成一条时序
|
||||
- **THEN** 该时序由趋势/周期/基线/噪声(含高斯与重尾 Student-t)成分叠加而成,且各成分参数被记录为元数据
|
||||
|
||||
### Requirement: 异常注入与精确标签
|
||||
|
||||
系统 SHALL 支持向合成时序注入多类异常,并把异常段位置与逐点标签作为 ground-truth 自动记录,标签与异常位置一致。
|
||||
|
||||
#### Scenario: 注入异常并记录逐点标签
|
||||
- **WHEN** 调用 `inject_anomaly(series, types)` 注入尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移中的任一类
|
||||
- **THEN** 返回 `(series, labels)`,其中 labels 为逐点 0/1,且 labels 中值为 1 的点与实际异常区间一致
|
||||
|
||||
#### Scenario: 异常稀有性兜底
|
||||
- **WHEN** 生成用于训练的样本
|
||||
- **THEN** 每条样本至少包含 1 类异常,保证异常类指令任务有正样本
|
||||
|
||||
### Requirement: 事件耦合
|
||||
|
||||
系统 SHALL 支持在指定时间点注入事件相关的阶跃变化,并生成对应的事件文本描述,以支撑时序+事件联合推理。
|
||||
|
||||
#### Scenario: 事件注入产生阶跃
|
||||
- **WHEN** 调用 `couple_event(series, t, kind)` 在时间 t 注入事件
|
||||
- **THEN** 时序在 t 处出现阶跃变化,并返回该事件的文本描述
|
||||
|
||||
### Requirement: 缺失与不规则采样模拟
|
||||
|
||||
系统 SHALL 支持随机丢弃部分时序点(用 NaN 占位),以模拟真实采集缺陷。
|
||||
|
||||
#### Scenario: 按比例丢弃点
|
||||
- **WHEN** 调用 `add_missing(series, rate=0.05~0.10)`
|
||||
- **THEN** 约 5-10% 的点被置为 NaN 占位
|
||||
|
||||
### Requirement: 属性词表采样
|
||||
|
||||
系统 SHALL 提供变量名词表(CPU/内存/流量/延迟/温度/请求量等)、单位与采样率档位,并按通道数采样返回结构化属性。
|
||||
|
||||
#### Scenario: 采样属性字段齐全
|
||||
- **WHEN** 调用 `sample_attributes(n_channels)`
|
||||
- **THEN** 返回长度为 n_channels 的列表,每项含 `name`、`unit`、`freq` 字段,且给定 seed 可复现
|
||||
|
||||
### Requirement: 多类指令与回答生成
|
||||
|
||||
系统 SHALL 支持 6 类指令任务(描述/统计、异常检测、根因/解释、预测、比较、事件关联),为每类生成指令,并产出可结构化解析的回答(异常类含 JSON 区间,统计类含数值,解释类含文本)。
|
||||
|
||||
#### Scenario: 异常类回答可被解析
|
||||
- **WHEN** 生成异常检测类的指令与回答
|
||||
- **THEN** 回答中的 JSON 可被 `json.loads` 解析,且其异常段与 labels 吻合
|
||||
|
||||
#### Scenario: 覆盖全部 6 类
|
||||
- **WHEN** 运行指令生成
|
||||
- **THEN** 6 类任务每类至少各产 1 条样本
|
||||
|
||||
### Requirement: 离线批量生成 JSONL
|
||||
|
||||
系统 SHALL 提供离线脚本多进程生成 JSONL 数据集,每条记录含 `series`/`attributes`/`timestamps`/`events`/`instruction`/`answer`/`labels`,并支持条数、输出路径、种子、并发数参数。
|
||||
|
||||
#### Scenario: 小规模生成产出合法 schema
|
||||
- **WHEN** 运行 `gen_synthetic.py --n 1000`
|
||||
- **THEN** 抽样 5 条每条均含上述 7 个字段,schema 合规
|
||||
|
||||
### Requirement: 真实 benchmark 加载与问答改写
|
||||
|
||||
系统 SHALL 能加载真实多变量时序 benchmark 窗口(至少 SWaT 与 MSL/MSL 系列中的 2 个),做滑窗+归一化+异常标签对齐,并把异常段改写为问答对(仅评测用,不进训练)。
|
||||
|
||||
#### Scenario: 加载并滑窗
|
||||
- **WHEN** 调用 `load_windows(name, T=512, stride=256)`
|
||||
- **THEN** 返回窗口形状 `[N, T, C]` 与标签形状 `[N, T]`,问答对非空
|
||||
@@ -0,0 +1,45 @@
|
||||
# Tasks · ts-as-modality
|
||||
|
||||
> 源自 `docs/superpowers/plans/2026-06-29-ts-as-modality-plan.md`(M1→M5)。
|
||||
> 每个里程碑末尾的「出口验证」为该阶段完成判据;建议先跑「冒烟路径」确认端到端通,再放大到全量。
|
||||
|
||||
## 1. M1 · 数据管线
|
||||
|
||||
- [ ] 1.1 项目脚手架:创建 `pyproject.toml`(torch/transformers/peft/accelerate/datasets/numpy/tqdm/pyyaml/pytest)、`src/tsmm/` 模块骨架、`configs/`、`scripts/`、`tests/`,并建 `data/`、`checkpoints/` 加 `.gitignore`(验证:`python -c "import tsmm"` 不报错;`pytest tests/` 可跑)
|
||||
- [ ] 1.2 属性词表与采样 `data/attributes.py`:定义变量名词表/单位/采样率档位,`sample_attributes(n_channels)` 返回结构化属性(验证:单测字段齐全、可复现)
|
||||
- [ ] 1.3 成分模型与时序合成 `data/synthesis.py`:`generate_series`(趋势+周期+基线+噪声)、`inject_anomaly`(尖刺/水平偏移/方差膨胀/缺失段/缓慢漂移,返回逐点 labels+段元数据)、`couple_event`(t 处阶跃+事件文本)、`add_missing`(NaN 占位)(验证:给定 seed 确定;异常段与 labels 一致;事件处有阶跃)
|
||||
- [ ] 1.4 指令与回答生成 `data/instruct.py`:6 类指令模板(描述/异常/根因/预测/比较/事件关联)+ Evol-Instruct 演化,`build_instruction` 产 JSON 区间/数值/文本回答(验证:异常类 JSON 可 `json.loads` 且段与 labels 吻合)
|
||||
- [ ] 1.5 离线生成脚本 `scripts/gen_synthetic.py`:多进程产 `align.jsonl`(50万)/`sft.jsonl`(10万)/`eval_synth.jsonl`(2k held-out),支持 `--n/--out/--seed/--workers` + tqdm(验证:`--n 1000` 跑通,抽样 5 条 schema 合规)
|
||||
- [ ] 1.6 真实 benchmark 加载 `data/real_bench.py`:加载 SMD/MSL/SMAP/SWaT/PSM(至少 2 个),`load_windows(T=512, stride=256)` 滑窗+归一化+标签,异常段改写问答对存 `eval_real.jsonl`(验证:窗口形状 `[N,T,C]`、标签 `[N,T]`、问答非空)
|
||||
- [ ] 1.7 M1 出口验证:`gen_synthetic.py --n 1000` 产可视检合法 JSONL;`real_bench.py` 加载 ≥2 数据集;人工抽看 5 条合成样本确认成分/异常/事件正确
|
||||
|
||||
## 2. M2 · 模型可跑通
|
||||
|
||||
- [ ] 2.1 TS Encoder `model/ts_encoder.py`:`Patchify(patch=8, stride=4)` 通道独立切 patch 线性嵌入到 d=256;`TSEncoder(d=256, layers=2, heads=4)` 2 层 TF + 可学习位置编码;前向 `[B,T,C]`→`[B,n_patches,256]`(验证:输入 `[2,512,5]`→`[2,128,256]`,参数 ≈4M)
|
||||
- [ ] 2.2 Projector `model/projector.py`:`Linear(256→896)+LayerNorm`(验证:输出 `[B,128,896]` 对齐 Qwen2.5-0.5B hidden)
|
||||
- [ ] 2.3 多模态拼接 `model/multimodal.py`:Qwen tokenizer tokenize 文本部分,TS token 作 inputs_embeds 插入 `[属性][时间戳][TS tok][事件][问题]`,统一构造 inputs_embeds+attention_mask+labels(仅回答段非 -100)(验证:seq_len ≤1024,mask/labels 形状对)
|
||||
- [ ] 2.4 训练/推理封装 `model/wrapper.py`:`MultimodalTSModel` 组合 Encoder+Projector+LLM+LoRA 挂载开关,`forward` 返 loss、`generate` 返文本,支持 `freeze_llm`(阶段①)/`enable_lora(r=16)`(阶段②)(验证:单 batch forward 3060 不 OOM;generate 能出文本)
|
||||
- [ ] 2.5 Collator `data/collator.py`:JSONL→batch 张量,处理变长 C(padding+mask)与变长文本(padding+attention_mask)(验证:batch=4 张量形状一致无 NaN)
|
||||
- [ ] 2.6 M2 出口验证:单 batch 前向+反向在 3060 跑通,loss 有限且下降趋势,阶段①模式峰值显存 ~5GB
|
||||
|
||||
## 3. M3 · 阶段①对齐训练
|
||||
|
||||
- [ ] 3.1 损失函数 `train/losses.py`:`lm_loss`(仅回答段计 loss)、`contrastive_loss`(扰动时序→回答 embedding 变化,InfoNCE/扰动一致性),总 loss=`lm_loss+λ*contrastive_loss`(λ 默认 0.1)(验证:loss 标量可反传,对比损失对扰动敏感)
|
||||
- [ ] 3.2 阶段①训练脚本 `train/stage1.py`+`scripts/train_stage1.sh`:加载 `align.jsonl` 流式,`freeze_llm=True` 仅训 Encoder+Projector(AdamW, lr=1e-4),bs=8/grad_accum=4/ctx=512/BF16/梯度检查点,每 2000 step 存 ckpt + TensorBoard(验证:`--max_steps 100` 冒烟不 OOM、loss 下降、峰值显存 ≤6GB)
|
||||
- [ ] 3.3 TS-token 有效性检验:held-out 原时序 vs 扰动时序回答变化率 + 「必看时序」样本答对率对照纯 LLM(验证:扰动后变化率 >50%,必看时序答对率显著高于纯 LLM)
|
||||
- [ ] 3.4 M3 出口验证:阶段① ckpt 产出;扰动检验通过;峰值显存 ≤6GB(失败回查对比损失权重/数据质量)
|
||||
|
||||
## 4. M4 · 阶段②SFT
|
||||
|
||||
- [ ] 4.1 阶段②训练脚本 `train/stage2.py`+`scripts/train_stage2.sh`:加载阶段① ckpt,`enable_lora(r=16)` on q/v_proj 其余冻结,加载 `sft.jsonl`,bs=4/grad_accum=8/ctx=1024/BF16/梯度检查点,每 2000 step 存含 LoRA ckpt(验证:`--max_steps 100` 冒烟不 OOM、loss 下降、峰值显存 ≤11GB)
|
||||
- [ ] 4.2 指令遵循抽检:6 类任务各取 10 条 held-out 检查回答(异常类 JSON 可解析+段合理;解释类切题引用事件)(验证:6 类回答可用率 >70%,JSON 解析成功率 >80%)
|
||||
- [ ] 4.3 M4 出口验证:阶段② ckpt 产出;6 类任务抽检达标;峰值显存 ≤11GB(OOM 则降 bs=2/grad_accum=16、`adamw_8bit`+CPU offload、ctx 降到 768)
|
||||
|
||||
## 5. M5 · 完整评测
|
||||
|
||||
- [ ] 5.1 回答解析 `eval/parse_answer.py`:文本回答→JSON 异常段→逐点分数 `[T]`,失败→全 0+失败标记(验证:多格式可解析、失败有兜底)
|
||||
- [ ] 5.2 异常检测指标 `eval/ts_metrics.py`:`tsb_uad` 算 VUS-PR(主),自实现 Affiliation-F1(多 λ)/AUC-PR/Point-F1(无PA),PA-F1 单独对照(验证:已知段算出合理值;trivial 全报异常 VUS-PR 不虚高)
|
||||
- [ ] 5.3 问答评测 `eval/qa_judge.py`:规则解析轨(JSON/数值容差→准确率)+ LLM-judge 轨(GPT-4o 打 0-5 分),不一致样本导出抽检(验证:对 eval 集产出 6 类任务的 {规则准确率,judge 均分,解析成功率})
|
||||
- [ ] 5.4 对照基线 `eval/baselines.py`:纯 LLM 数值喂文本 / Time-LLM 风格重映射 / ChatTS(若可复现) / Trivial(Random/Constant/全报异常),全走同一套 parse+metrics(验证:4 类基线产出同口径指标表)
|
||||
- [ ] 5.5 评测脚本与报告 `scripts/run_eval.sh`:跑 `eval_synth.jsonl`+`eval_real.jsonl`,产 `reports/eval-YYYYMMDD.md`(含每数据集×每任务全部必报指标、标注是否用 PA、含 trivial 对照)(验证:一键产出满足设计规格 §5.4 必报清单的完整报告)
|
||||
- [ ] 5.6 M5 出口验证:报告满足设计规格 §6.5 成功标准——真实 benchmark VUS-PR 显著优于纯 LLM 基线;时序消融后指标明显下降;问答均分超基线;评测可复现含 trivial
|
||||
Reference in New Issue
Block a user