diff --git a/README.md b/README.md new file mode 100644 index 0000000..1f7ad92 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +# Video-Tree-TRM5 + +> 在层次化视频树上构建可自我进化的搜索 Agent 与可训练递归检索器,实现长视频理解。目标会议:EMNLP 2026。 + +## 系统概览 + +本项目是 Video-Tree-TRM4(MVP)的生产级重构,采用 Clean Architecture 分层设计。 + +### 核心思想:自进化循环对标 PyTorch 训练 + +| PyTorch | 本项目 | 模块 | +|---------|--------|------| +| DataLoader | 出题 question_gen | `app/question_gen/` | +| model.forward() | 推理 inference | `app/harness/inference.py` + `core/agent/loop.py` | +| loss.backward() | 诊断 diagnose | `core/evolution/diagnose.py` | +| optimizer.step() | 进化 evolve | `core/evolution/evolve.py` | +| nn.Parameter | Skills + Prompts(版本化) | `store/skills/`, `store/prompts/` | + +### 三大模块 + +| 模块 | 目录 | 说明 | +|------|------|------| +| 建树 | `app/tree/` | 离线预处理:VLM 生成三层 TreeIndex(L1段落→L2片段→L3帧),支持字幕注入和后增强 | +| 训练 | `app/harness/` + `core/` | 自进化循环:推理→诊断→进化,含 CE-Gate 统计检验、信息阶梯、mini-batch 调度 | +| 新题构建 | `app/question_gen/` | 生成 Video-MME 风格训练题,原始 benchmark 作 held-out 泛化评测 | + +### 可提取内核 + +`core/agent/` 和 `core/evolution/` 只依赖 Protocol 接口,可独立提取用于其他项目。 + +## 快速开始 + +```bash +# 1. 创建 Conda 环境 +conda create -n Video-Tree-TRM python=3.11 -y +conda activate Video-Tree-TRM +pip install -e ".[dev]" + +# 2. 配置环境变量 +cp .env.example .env +# 编辑 .env 填入 API 密钥 + +# 3. 验证 +make lint +make test +``` + +## 项目结构 + +详见 `research-wiki/ARCHITECTURE.md`。 + +## 文档 + +| 文档 | 说明 | +|------|------| +| `research-wiki/ARCHITECTURE.md` | 系统架构与边界 | +| `research-wiki/overview.md` | 自进化循环总览 | +| `CLAUDE.md` | Agent 工作指令 | +| `reference/docs/architecture.md` | 建树+检索器参考设计 | diff --git a/adapters/__init__.py b/adapters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/harness/__init__.py b/app/harness/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/ports.py b/app/ports.py new file mode 100644 index 0000000..ed6ba2e --- /dev/null +++ b/app/ports.py @@ -0,0 +1 @@ +"""应用层 Protocol 端口定义。""" diff --git a/app/question_gen/__init__.py b/app/question_gen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/retriever/__init__.py b/app/retriever/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/search/__init__.py b/app/search/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tree/__init__.py b/app/tree/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tree/enhance/__init__.py b/app/tree/enhance/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/agent/__init__.py b/core/agent/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/evolution/__init__.py b/core/evolution/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/types.py b/core/types.py new file mode 100644 index 0000000..28ca3cb --- /dev/null +++ b/core/types.py @@ -0,0 +1 @@ +"""跨模块共享类型。""" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..643ee1b --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,59 @@ +[build-system] +requires = ["setuptools>=68.0", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "video-tree-trm" +version = "0.1.0" +description = "自进化搜索 Agent + 可训练递归检索器,在层次化视频树上实现长视频理解" +requires-python = ">=3.11" +dependencies = [ + "torch>=2.1", + "pluggy>=1.3", + "loguru>=0.7", + "openai>=1.30", + "httpx>=0.27", + "sentence-transformers>=3.0", + "numpy>=1.26", + "pydantic>=2.5", + "pydantic-settings>=2.1", + "pyyaml>=6.0", + "python-dotenv>=1.0", + "opencv-python-headless>=4.9", + "json-repair>=0.28", + "arq>=0.26", + "redis>=5.0", +] + +[project.optional-dependencies] +dev = [ + "pytest>=8.0", + "pytest-cov>=5.0", + "pytest-asyncio>=0.23", + "ruff>=0.5", + "radon>=6.0", +] + +[tool.setuptools.packages.find] +include = ["core*", "app*", "adapters*"] + +[tool.pytest.ini_options] +pythonpath = [".", ".claude/tools"] +testpaths = ["tests"] +markers = [ + "requires_redis: 需要可达的 Redis(无则 skip)", + "requires_gpu: 需要 GPU(无则 skip)", + "slow: 慢速测试(CI 按需跑)", +] +asyncio_mode = "auto" + +[tool.ruff] +target-version = "py311" +line-length = 100 + +[tool.ruff.lint] +select = ["E", "F", "W", "I", "N", "UP", "B", "A", "C4", "SIM", "TCH"] +ignore = ["E501"] + +[tool.ruff.lint.isort] +known-first-party = ["core", "app", "adapters"] diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/test_smoke.py b/tests/unit/test_smoke.py new file mode 100644 index 0000000..b16e7c2 --- /dev/null +++ b/tests/unit/test_smoke.py @@ -0,0 +1,19 @@ +"""冒烟测试:验证包可导入。""" + + +def test_core_importable(): + """core 包可导入。""" + import core + assert core is not None + + +def test_app_importable(): + """app 包可导入。""" + import app + assert app is not None + + +def test_adapters_importable(): + """adapters 包可导入。""" + import adapters + assert adapters is not None