talkingheadbench / README.md
elix3r's picture
Upload folder using huggingface_hub
ab34aa7 verified
|
Raw
History Blame Contribute Delete
13.1 kB
---
title: TalkingHeadBench
emoji: 🎭
colorFrom: indigo
colorTo: purple
sdk: docker
app_port: 8000
pinned: false
license: mit
short_description: Talking-head LoRA diagnostic reasoning benchmark
base_path: /web
---
# TalkingHeadBench 🎭
> **An open-source diagnostic reasoning benchmark for evaluating AI agents on talking-head video LoRA pipelines.**
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![OpenEnv](https://img.shields.io/badge/OpenEnv-v1.0-green.svg)](https://github.com/meta-pytorch/OpenEnv)
[![HuggingFace](https://img.shields.io/badge/πŸ€—-LTX--2.3--22b--AV--LoRA-orange)](https://huggingface.co/elix3r/LTX-2.3-22b-AV-LoRA-talking-head)
---
## Overview
**TalkingHeadBench** challenges AI agents to act as **senior engineers** who audit and optimize talking-head video LoRA pipelines β€” identifying failure modes in reference images, training datasets, and final model weights *before a single frame is ever rendered*.
The benchmark focuses on **diagnostic reasoning**, not generative performance. All signals are pre-extracted (face occupancy ratios, yaw/pitch degrees, landmark stability scores, canonical SVD weight components), making episodes run in **seconds** without GPU inference.
---
## πŸ—οΈ Architecture
The pipeline is divided into **3 coupled sub-environments** spanning **9 deterministic nodes**:
```
Episode
β”œβ”€β”€ Sub-env 1 β€” Reference Image & Prompt Audit (weight: 25%)
β”‚ β”œβ”€β”€ Node 1 β€” Image Diagnostician
β”‚ β”œβ”€β”€ Node 2 β€” Parameter Anomaly Detector
β”‚ └── Node 3 β€” Grader
β”‚
β”œβ”€β”€ Sub-env 2 β€” Dataset Clip Health Audit (weight: 35%)
β”‚ β”œβ”€β”€ Node 4 β€” Clip Signal Extractor
β”‚ β”œβ”€β”€ Node 5 β€” Disposition Classifier
β”‚ └── Node 6 β€” Grader
β”‚
└── Sub-env 3 β€” Trained LoRA Weight Behavioral Audit (weight: 40%)
β”œβ”€β”€ Node 7 β€” Weight Signal Extractor
β”œβ”€β”€ Node 8 β€” Phoneme Risk Assessor
└── Node 9 β€” Behavioral Audit Grader
```
### Non-Linear Coupling
Sub-environments are **hard-coupled**: a poor audit in Sub-env 1 (e.g., missing a lateral pose risk) causes Sub-env 2 to receive harder dataset clips with deeper identity drift, mirroring real-world cascading failures.
### Final Reward Formula
```
final_score = 0.25 Γ— subenv1 + 0.35 Γ— subenv2 + 0.40 Γ— subenv3
```
See [`REWARD_LOGIC.md`](REWARD_LOGIC.md) for per-dimension scoring breakdowns.
---
## πŸ“ Project Structure
```
TalkingHeadBench/
β”œβ”€β”€ src/
β”‚ β”œβ”€β”€ pipeline.py # Episode orchestrator (run_episode_from_bundle)
β”‚ β”œβ”€β”€ evaluate.py # CLI evaluation harness (dry-run + scoring)
β”‚ β”œβ”€β”€ envs/
β”‚ β”‚ β”œβ”€β”€ subenv1/
β”‚ β”‚ β”‚ β”œβ”€β”€ node1_image_diagnostician.py
β”‚ β”‚ β”‚ β”œβ”€β”€ node2_param_anomaly.py
β”‚ β”‚ β”‚ └── node3_grader.py
β”‚ β”‚ β”œβ”€β”€ subenv2/
β”‚ β”‚ β”‚ β”œβ”€β”€ node4_clip_extractor.py
β”‚ β”‚ β”‚ β”œβ”€β”€ node5_disposition.py
β”‚ β”‚ β”‚ └── node6_grader.py
β”‚ β”‚ └── subenv3/
β”‚ β”‚ β”œβ”€β”€ node7_weight_extractor.py
β”‚ β”‚ β”œβ”€β”€ node8_phoneme_risk.py
β”‚ β”‚ └── node9_grader.py
β”‚ β”œβ”€β”€ schemas/
β”‚ β”‚ β”œβ”€β”€ subenv1.py # Pydantic models: ImageDiagnosticsObservation, etc.
β”‚ β”‚ β”œβ”€β”€ subenv2.py # Pydantic models: ClipSignalObservation, etc.
β”‚ β”‚ β”œβ”€β”€ subenv3.py # Pydantic models: WeightSignalObservation, etc.
β”‚ β”‚ └── ground_truth.py # GroundTruth schema for all sub-envs
β”‚ └── utils/
β”‚ β”œβ”€β”€ canonical.py # Canonical SVD + weight decomposition utilities
β”‚ └── grader_utils.py # Shared scoring helpers (F1, NDCG, recall)
β”‚
β”œβ”€β”€ server/
β”‚ β”œβ”€β”€ app.py # FastAPI app (OpenEnv-compliant /reset, /step)
β”‚ β”œβ”€β”€ talking_head_environment.py # Gymnasium-style environment wrapper
β”‚ β”œβ”€β”€ Dockerfile # Container definition
β”‚ └── requirements.txt # Server-side dependencies
β”‚
β”œβ”€β”€ tests/
β”‚ β”œβ”€β”€ unit/ # Unit tests for individual nodes and schemas
β”‚ β”‚ β”œβ”€β”€ test_node4_extractor.py
β”‚ β”‚ β”œβ”€β”€ test_node7_extractor.py
β”‚ β”‚ β”œβ”€β”€ test_canonical.py
β”‚ β”‚ β”œβ”€β”€ test_graders.py
β”‚ β”‚ β”œβ”€β”€ test_schemas.py
β”‚ β”‚ β”œβ”€β”€ test_subenv1.py
β”‚ β”‚ β”œβ”€β”€ test_subenv2.py
β”‚ β”‚ └── test_subenv3.py
β”‚ └── smoke/ # Integration & boundary tests
β”‚ β”œβ”€β”€ test_pipeline_e2e.py
β”‚ β”œβ”€β”€ test_pipeline_bundle.py
β”‚ β”œβ”€β”€ test_schema_roundtrip.py
β”‚ β”œβ”€β”€ test_grader_arithmetic.py
β”‚ β”œβ”€β”€ test_node1_boundaries.py
β”‚ β”œβ”€β”€ test_node2_boundaries.py
β”‚ β”œβ”€β”€ test_node5_boundaries.py
β”‚ β”œβ”€β”€ test_node7_deep.py
β”‚ β”œβ”€β”€ test_node8_boundaries.py
β”‚ β”œβ”€β”€ test_evaluate_cli.py
β”‚ └── test_validate_annotations_cli.py
β”‚
β”œβ”€β”€ scripts/
β”‚ β”œβ”€β”€ extract_subenv1_signals.py # Signal extraction for Sub-env 1
β”‚ β”œβ”€β”€ extract_subenv2_signals.py # Signal extraction for Sub-env 2
β”‚ β”œβ”€β”€ extract_subenv3_signals.py # Signal extraction for Sub-env 3
β”‚ β”œβ”€β”€ generate_annotation_worksheet.py
β”‚ β”œβ”€β”€ validate_annotations.py
β”‚ β”œβ”€β”€ convert_captions.py
β”‚ └── export_test_set.py
β”‚
β”œβ”€β”€ docs/
β”‚ β”œβ”€β”€ PROJECT_OVERVIEW.md
β”‚ β”œβ”€β”€ OPENENV_INTEGRATION_GUIDE.md
β”‚ β”œβ”€β”€ CODEBASE_REVIEW.md
β”‚ └── annotation_worksheet_subenv{1,2,3}.md
β”‚
β”œβ”€β”€ client.py # OpenEnv client helper
β”œβ”€β”€ openenv.yaml # OpenEnv manifest (runtime: fastapi, port: 8000)
β”œβ”€β”€ pyproject.toml # Package config (openenv-talking-head-bench v1.0.0)
β”œβ”€β”€ requirements.txt # Top-level dependencies
β”œβ”€β”€ REWARD_LOGIC.md # Detailed scoring documentation
└── LICENSE # MIT
```
---
## πŸš€ Quick Start
### Prerequisites
- Python 3.10+
- pip or [uv](https://github.com/astral-sh/uv)
### Installation
```bash
git clone https://github.com/22elix3r/TalkingHeadBench.git
cd TalkingHeadBench
# Standard pip
pip install -r requirements.txt
# Or install as a package (recommended for OpenEnv usage)
pip install -e ".[dev]"
```
### Run an Episode (Python API)
```python
from src.pipeline import run_episode_from_bundle, EpisodeResult
bundle = {
"reference_image_obs": {
# ImageDiagnosticsObservation fields
"face_occupancy_ratio": 0.42,
"yaw_degrees": 28.5,
"pitch_degrees": -4.1,
"landmark_stability_score": 0.81,
# ...
},
"param_config": {
"cfg": 5.5,
"denoise_alt": 0.5,
"eta": 0.08
},
"clip_signal_obs_list": [
# list of ClipSignalObservation dicts
],
"weight_obs": {
# WeightSignalObservation fields
},
"ground_truths": {
# ground truth annotations for all sub-envs
},
}
result: EpisodeResult = run_episode_from_bundle(bundle)
print(f"Final score: {result.final_score:.3f}")
print(f" Sub-env 1: {result.subenv1_score:.3f}")
print(f" Sub-env 2: {result.subenv2_score:.3f}")
print(f" Sub-env 3: {result.subenv3_score:.3f}")
```
### CLI Evaluation Harness
```bash
# Dry-run (schema validation only)
python -m src.evaluate --dry-run --test-set tests/test_set/
# Full scoring run
python -m src.evaluate --test-set tests/test_set/ --verbose
```
---
## 🌐 OpenEnv Server
TalkingHeadBench is packaged as an [OpenEnv](https://github.com/meta-pytorch/OpenEnv)-compliant environment with a Gymnasium-style `reset` / `step` API served over FastAPI.
### Run Locally
```bash
pip install openenv-core[core]>=0.2.2
uvicorn server.app:app --host 0.0.0.0 --port 8000
```
### Run with Docker
```bash
docker build -t talking-head-bench -f server/Dockerfile .
docker run -p 8000:8000 talking-head-bench
```
### Client Usage
```python
from client import TalkingHeadBenchEnv
with TalkingHeadBenchEnv(base_url="http://localhost:8000").sync() as env:
obs = env.reset() # Receives ImageDiagnosticsObservation
obs = env.step(action_1) # Sub-env 1 decision β†’ receives ParamAnomalyObservation
obs = env.step(action_2) # Sub-env 2 decision β†’ receives WeightSignalObservation
obs = env.step(action_3) # Sub-env 3 decision β†’ episode done
print(obs.reward) # Final weighted score
```
### Episode Flow
| Step | Transition | Agent Receives | Agent Returns |
|------|-----------|----------------|---------------|
| `reset` | β€” | `ImageDiagnosticsObservation` | β€” |
| `step 1` | Node 1 β†’ Node 2 | `ParamAnomalyObservation` | `ImageDiagnosticsAction` |
| `step 2` | Node 4 β†’ Node 6 | `ClipDispositionObservation` | `ParamAnomalyAction` |
| `step 3` | Node 7 β†’ Node 9 | done + `final_score` | `PhonemeRiskAction` |
---
## πŸ§ͺ Test Suite
```bash
# Run all tests
pytest
# Unit tests only
pytest tests/unit/
# Smoke / integration tests
pytest tests/smoke/
# With coverage
pytest --cov=src --cov-report=term-missing
```
| Test Module | Coverage Area |
|---|---|
| `test_schemas.py` | Pydantic model validation (all sub-envs) |
| `test_schema_roundtrip.py` | Schema serialization / deserialization |
| `test_grader_arithmetic.py` | Reward formula correctness |
| `test_node1_boundaries.py` | Node 1 edge cases |
| `test_node2_boundaries.py` | Node 2 edge cases |
| `test_node4_extractor.py` | Clip signal extraction |
| `test_node5_boundaries.py` | Disposition classifier boundaries |
| `test_node7_extractor.py` | Weight signal extraction |
| `test_node7_deep.py` | Deep Node 7 heuristic tests |
| `test_node8_boundaries.py` | Phoneme risk assessor boundaries |
| `test_pipeline_e2e.py` | Full episode end-to-end |
| `test_pipeline_bundle.py` | Bundle format validation |
| `test_evaluate_cli.py` | CLI harness integration |
---
## πŸ“Š Scoring Reference
### Sub-env 1 β€” Reference Image & Prompt Audit (25%)
| Dimension | Weight | Method |
|-----------|--------|--------|
| Regime Classification | 0.35 | Exact match (1.0), borderline (0.7), wrong (0.0) |
| Risk Factor Recall | 0.35 | Set intersection recall |
| Prompt Modification Validity | 0.30 | Precision against curated valid set |
### Sub-env 2 β€” Dataset Clip Health Audit (35%)
| Dimension | Weight | Method |
|-----------|--------|--------|
| Disposition Match | 0.40 | Exact + confidence calibration |
| Fix Instruction Quality | 0.20 | Precision β‰₯ 0.8 β†’ full, β‰₯ 0.5 β†’ half |
| Dataset Impact Reasoning | 0.20 | Keyword element matching |
| Override Misuse Penalty | βˆ’0.10 | Unjustified override β†’ penalty |
### Sub-env 3 β€” LoRA Weight Behavioral Audit (40%)
| Dimension | Weight | Method |
|-----------|--------|--------|
| Phoneme Risk Ranking | 0.25 | NDCG against reference ranking |
| Behavior Trigger Prediction | 0.20 | Set F1 on (phoneme, behavior) pairs |
| Cluster Identification | 0.20 | Overlap with reference clusters |
| Safety Calibration | 0.15 | Ordinal distance |
| Mitigation Quality | 0.20 | (target, action) pair matching |
---
## πŸ€— Reference Model
This benchmark is designed to evaluate agents working with:
πŸ”— **[elix3r/LTX-2.3-22b-AV-LoRA-talking-head](https://huggingface.co/elix3r/LTX-2.3-22b-AV-LoRA-talking-head)**
---
## Design Principles
| Property | Description |
|----------|-------------|
| **No live generation** | All signals are pre-extracted; no GPU inference required during evaluation |
| **Deterministic** | All graders are rule-based β€” no LLM judge, fully reproducible |
| **Partial credit** | Borderline answers receive scaled scores, not binary pass/fail |
| **Cascading difficulty** | Sub-env 1 risk profile influences Sub-env 2 context |
| **Fast episodes** | Full evaluation completes in seconds |
---
## πŸ“– Documentation
| Document | Description |
|----------|-------------|
| [`docs/PROJECT_OVERVIEW.md`](docs/PROJECT_OVERVIEW.md) | Full architecture and design reference |
| [`docs/OPENENV_INTEGRATION_GUIDE.md`](docs/OPENENV_INTEGRATION_GUIDE.md) | OpenEnv compliance and deployment guide |
| [`docs/CODEBASE_REVIEW.md`](docs/CODEBASE_REVIEW.md) | File-by-file codebase audit |
| [`REWARD_LOGIC.md`](REWARD_LOGIC.md) | Detailed scoring and reward formula |
---
## Citation
```bibtex
@software{TalkingHeadBench2026,
author = {elix3r},
title = {TalkingHeadBench: A Diagnostic Reasoning Benchmark for Talking-Head LoRA Pipelines},
year = {2026},
url = {https://github.com/22elix3r/TalkingHeadBench},
version = {1.0.0}
}
```
---
## License
Licensed under the **MIT License** β€” see [`LICENSE`](LICENSE) for details.