Files
subtitle-generate/MVP-DESIGN.md
T

11 KiB
Raw Blame History

AI Workflow Platform MVP Design

1. MVP 目标

用最小但完整的闭环验证这个架构:管理员在后台注册节点、编排工作流并发布;普通用户只上传视频,后端动态组装节点并执行;节点无人使用后自动回收。

MVP 只做单机版本,不做 Kubernetes、多租户、计费和分布式 GPU 池。目标是在一台机器上跑通:

上传视频 -> ffmpeg 提音 -> faster-whisper 转写 -> LLM 翻译 -> VR ASS 生成 -> 下载结果

2. 整体架构

flowchart LR
    Admin[管理后台] --> AdminAPI[FastAPI Admin API]
    AdminAPI --> DB[(SQLite)]
    AdminAPI --> Registry[节点注册中心]
    Registry --> Manager[节点管理器]
    Manager --> NodeA[ASR 节点]
    Manager --> NodeB[LLM 节点]
    Manager --> NodeC[ASS 节点]

    User[用户前端] --> UserAPI[FastAPI User API]
    UserAPI --> Scheduler[工作流调度器]
    Scheduler --> Registry
    Scheduler --> Runs[WorkflowRun]
    Runs --> DB
    Scheduler --> Manager

关键原则:

  • 节点不是写死在应用里的函数,而是独立进程,按统一协议提供服务。
  • 工作流是数据库里的版本化 DAG,不是业务代码。
  • 调度器只负责编排,不直接加载模型。
  • 节点实例由节点管理器统一创建、分配、回收。

3. MVP 范围

3.1 本期包含

  • 节点注册中心,支持登记节点类型、能力、参数、启动命令、资源要求。
  • 节点生命周期:COLD / STARTING / READY / BUSY / IDLE / STOPPING。
  • 工作流 DAG 定义、校验、版本化、发布。
  • 单机工作流执行器,按拓扑顺序调度节点。
  • 用户上传接口、任务状态查询、进度事件、产物下载。
  • 管理后台节点管理和工作流画布。
  • 用户端工作流列表、上传页、进度页、结果页。
  • 一条可运行的视频字幕示例工作流。

3.2 本期不做

  • Kubernetes、GPU 自动扩缩、跨机器节点池。
  • 多租户、用户认证、计费、配额。
  • 节点在线热部署和插件市场。
  • 可视化工作流调试器。
  • 分布式任务队列和 Worker 集群。

4. 节点抽象

4.1 节点 Manifest

{
  "id": "faster-whisper",
  "name": "Faster Whisper ASR",
  "version": "1.0.0",
  "capability": "asr",
  "command": ["python", "-m", "nodes.whisper_node"],
  "env": {
    "MODEL_PATH": "./models/faster-whisper-large-v3"
  },
  "input_schema": {
    "audio_uri": "file"
  },
  "output_schema": {
    "srt_uri": "file"
  },
  "max_concurrency": 1,
  "idle_ttl_seconds": 300,
  "health_timeout_seconds": 10
}

字段含义:

  • capability:节点能力类型,例如 asrllmffmpegsubtitle
  • command:节点进程启动命令。
  • env:模型路径、API Key 等环境变量。
  • input_schema / output_schema:用于工作流校验和节点参数检查。
  • max_concurrency:单实例最大并发任务数。
  • idle_ttl_seconds:空闲多久后回收。

4.2 节点进程协议

每个节点是一个独立进程,对外提供两个 HTTP 接口:

GET /health
POST /invoke

POST /invoke 请求:

{
  "run_id": "run_123",
  "node_instance_id": "ni_456",
  "inputs": {
    "audio_uri": "storage/runs/run_123/audio.wav"
  },
  "params": {
    "language": "ja",
    "beam_size": 1
  },
  "output_dir": "storage/runs/run_123/steps/whisper"
}

POST /invoke 响应:

{
  "status": "completed",
  "outputs": {
    "srt_uri": "storage/runs/run_123/steps/whisper/output.srt"
  }
}

节点执行过程中可以上报进度事件:

{
  "run_id": "run_123",
  "node_id": "faster-whisper",
  "progress": 0.45,
  "message": "正在转录第 120/300 段"
}

MVP 阶段节点通过本地文件系统交换产物,未来把 storage/... 换成对象存储 URI 即可。

4.3 节点生命周期

COLD -> STARTING -> READY -> BUSY -> READY -> IDLE -> STOPPING -> STOPPED
                    |                              |
                    +---------- ERROR <------------+
  • COLD:没有进程,只有注册信息。
  • STARTING:进程已拉起,等待 /health 就绪。
  • READY:进程就绪,模型已加载,可以接收任务。
  • BUSY:正在执行任务。
  • IDLE:任务完成,等待下一任务或回收。
  • STOPPING:超过 idle_ttl_seconds,正在优雅退出。
  • ERROR:启动或执行失败。

节点管理器定时扫描实例状态:

  • 任务申请节点时,优先分配 READY 实例。
  • 没有实例时,从 COLD 启动。
  • BUSY 实例不能被回收。
  • IDLE 超过 TTL 后先卸载模型并停止进程。
  • 被调度器标记为长期热门的节点可以配置 keep_warm=true,不回收。

5. 工作流定义

工作流是一份带版本号的 DAG JSON:

{
  "name": "video-to-vr-ass",
  "version": 1,
  "nodes": [
    {
      "id": "extract",
      "node_type": "ffmpeg-extract",
      "params": {
        "sample_rate": 16000,
        "channels": 1
      }
    },
    {
      "id": "asr",
      "node_type": "faster-whisper",
      "params": {
        "language": "ja"
      }
    },
    {
      "id": "translate",
      "node_type": "llm-translate",
      "params": {
        "target_language": "zh-CN"
      }
    },
    {
      "id": "ass",
      "node_type": "srt-to-dual-eye-ass",
      "params": {
        "resolution": "3840x1920"
      }
    }
  ],
  "edges": [
    {"from": "extract", "to": "asr"},
    {"from": "asr", "to": "translate"},
    {"from": "translate", "to": "ass"}
  ],
  "entry_inputs": {
    "video_uri": "file"
  },
  "final_outputs": {
    "cn_srt": "translate.srt_uri",
    "ass": "ass.ass_uri"
  }
}

工作流校验规则:

  • 所有 node_type 必须已注册。
  • 边必须引用存在的节点。
  • 每个节点的输入必须有上游产物或工作流入口输入。
  • 工作流必须是无环图。
  • 发布前必须通过一次 dry-run 校验。

6. 执行模型

用户触发工作流后:

  1. 创建 WorkflowRun,状态为 QUEUED
  2. 调度器读取工作流 DAG,做拓扑排序。
  3. 对每个节点调用节点管理器申请实例。
  4. 节点执行完毕后,产物 URI 写入 Artifact
  5. 所有节点完成后,WorkflowRun 状态变为 COMPLETED
  6. 任一节点失败,按重试策略重试;超过次数后标记 FAILED

MVP 的调度策略:

  • 只支持线性链和简单 DAG。
  • 没有依赖关系的节点可以并发执行。
  • 节点之间只通过产物 URI 通信,不允许共享内存。
  • 每个节点执行前检查健康状态,节点不可用时重新启动。

WorkflowRun 状态:

QUEUED -> RUNNING -> COMPLETED
            |          |
            +-> FAILED +
            |
            +-> CANCELLED

7. 数据模型

MVP 使用 SQLite,表结构如下。

nodes

id, name, version, capability, manifest_json, status, created_at

workflows

id, name, slug, description, published, latest_version, created_at

workflow_versions

id, workflow_id, version, definition_json, created_at

workflow_runs

id, workflow_id, workflow_version, status, current_node_id,
progress, error, input_uri, created_at, updated_at

node_instances

id, node_id, status, pid, address, started_at, last_used_at,
busy_since, error

artifacts

id, run_id, node_id, name, uri, mime_type, size, created_at

8. API 设计

管理端

GET    /api/admin/nodes
POST   /api/admin/nodes
GET    /api/admin/nodes/{node_id}
DELETE /api/admin/nodes/{node_id}

GET    /api/admin/node-instances
POST   /api/admin/node-instances/{id}/stop

GET    /api/admin/workflows
POST   /api/admin/workflows
GET    /api/admin/workflows/{workflow_id}
PUT    /api/admin/workflows/{workflow_id}
POST   /api/admin/workflows/{workflow_id}/validate
POST   /api/admin/workflows/{workflow_id}/publish

用户端

GET  /api/apps
POST /api/apps/{workflow_id}/runs
GET  /api/runs/{run_id}
GET  /api/runs/{run_id}/events
GET  /api/runs/{run_id}/artifacts/{artifact_name}

上传接口使用 multipart/form-data

POST /api/apps/{workflow_id}/runs
Content-Type: multipart/form-data
body: file=video.mp4

进度接口使用 SSE

GET /api/runs/{run_id}/events
Accept: text/event-stream

9. 前端设计

管理后台

页面:

  • /admin/nodes:节点注册列表。
  • /admin/workflows:工作流列表。
  • /admin/workflows/{id}React Flow 画布。
  • /admin/workflows/{id}/publish:发布确认。

画布能力:

  • 左侧节点面板,按 capability 分组。
  • 拖拽节点到画布。
  • 节点参数面板。
  • 保存、校验、发布。

MVP 不实现节点在线调试器,只实现“保存 -> 校验 -> 发布 -> 后台试跑”。

用户端

页面:

  • /:已发布工作流列表。
  • /app/{workflow_id}:上传页。
  • /runs/{run_id}:进度页和结果下载。

用户端不展示任何工作流细节,只展示输入表单、进度、产物。

10. 示例工作流

节点清单

节点 capability 作用
ffmpeg-extract media 提取 16kHz 单声道音频
faster-whisper asr 日语语音转写为 SRT
srt-normalize subtitle 清洗 SRT 格式
llm-translate llm 调用 Ollama/OpenAI 兼容接口翻译
srt-to-dual-eye-ass subtitle 生成 VR 双眼 ASS

验收标准

  1. 管理员注册上述节点,画一条工作流并发布。
  2. 用户上传一个测试视频。
  3. 后端自动按 DAG 执行提音、转写、翻译、ASS 转换。
  4. 用户能看到进度并能下载 .CN.srt_dual_eye.ass
  5. 节点空闲超过 TTL 后进程被回收。
  6. 新注册一个 ASR 节点后,编辑器中可以替换节点并重新发布,不需要改业务代码。

11. 技术选型

Backend:  Python 3.12 + FastAPI + Pydantic + SQLite
Executor: 单进程调度器 + 子进程节点
Node host: Python HTTP 服务(Uvicorn
Storage:  本地 storage/ 目录
Admin UI: React + Vite + React Flow
User UI:  React + Vite
Deploy:   Docker Compose

MVP 不引入 Redis 和 Celery,因为单机单调度器已经可以演示核心概念。任务状态持久化在 SQLite,节点状态由节点管理器维护。

12. 实现里程碑

M1:节点基础能力

  • 节点注册表。
  • 节点管理器。
  • 一个 echo 示例节点。
  • 节点生命周期与 TTL 回收。

M2:工作流执行

  • 工作流 CRUD 和版本化。
  • DAG 校验。
  • 调度器按拓扑顺序执行。
  • WorkflowRun 状态机和产物管理。

M3:用户服务闭环

  • 上传接口。
  • 任务状态和 SSE 进度。
  • 产物下载。

M4:管理后台 UI

  • React Flow 工作流画布。
  • 节点注册页面。
  • 发布流程。

M5:字幕演示工作流

  • ffmpeg 提音。
  • faster-whisper 转写。
  • LLM 翻译。
  • SRT 转 VR 双眼 ASS。
  • 完整端到端验收。

13. 后续扩展路径

  • SQLite -> PostgreSQL。
  • 本地文件 -> MinIO/S3。
  • 单机调度器 -> Redis + Celery/Temporal。
  • 子进程节点 -> 容器节点 + Kubernetes。
  • 节点管理器 -> KEDA 自动扩缩和 scale-to-zero。
  • 注册表 -> 插件市场。
  • 单用户 -> 多租户、鉴权、配额、计费。