No description
  • Python 87.8%
  • Shell 9.6%
  • Dockerfile 2.6%
Find a file
2026-06-11 22:01:05 +08:00
argo feat:update argo template 2026-06-10 18:36:35 +08:00
backend feat: add Argo Workflows pipeline for QNN model conversion 2026-06-10 13:54:25 +08:00
docker feat: add Argo Workflows pipeline for QNN model conversion 2026-06-10 13:54:25 +08:00
docs over 2026-06-11 22:01:05 +08:00
scripts feat:add realtime log check api 2026-06-09 23:49:32 +08:00
.gitignore core v0.0.1 2026-06-05 18:08:34 +08:00
.python-version core v0.0.1 2026-06-05 18:08:34 +08:00
build.sh feat:add realtime log check api 2026-06-09 23:49:32 +08:00
install.sh 修改deployment 配置认证 2026-06-08 23:40:23 +08:00
main.py core v0.0.1 2026-06-05 18:08:34 +08:00
pyproject.toml feat:change db to pgsql 2026-06-09 16:34:04 +08:00
README.md feat: add Argo Workflows pipeline for QNN model conversion 2026-06-10 13:54:25 +08:00
uv.lock feat:change db to pgsql 2026-06-09 16:34:04 +08:00

ModelForge 模型锻造平台技术架构设计文档

1. 项目定位

ModelForge 是一个面向模型转换、优化、验证与可复现执行的轻量级平台。

平台第一阶段聚焦 QNN 模型转换与优化,后续可扩展支持更多模型后端,例如 TensorRT、OpenVINO、ONNX Runtime、TFLite、NCNN 等。

系统底层是一个容器化任务执行平台,上层是面向非专业用户的一键式模型转换与优化产品。

整体定位:

ModelForge = 模型转换优化产品 + 可复现容器任务平台

对普通用户:

上传模型 -> 选择目标平台 -> 选择优化策略 -> 一键转换 -> 下载结果

对算法工程师和平台工程师:

任务模板 -> 容器执行 -> 日志追踪 -> 产物留痕 -> 调试复现

2. 设计目标

2.1 产品目标

平台需要让非专业用户通过简单网页操作完成模型转换和优化。

用户不需要理解:

Kubernetes
Docker
Pod
Job
MinIO
Manifest
命令行参数
容器镜像

用户只需要理解:

模型文件
目标平台
优化等级
转换结果
报告下载

2.2 技术目标

平台底层需要支持:

  1. 容器化任务执行。
  2. 单机 K3s 部署。
  3. 每个任务独立运行。
  4. 输入、输出、日志、配置完整留痕。
  5. 任务可复现。
  6. 任务可克隆。
  7. 任务可调试。
  8. 支持进入运行中容器排查问题。
  9. 后续可扩展到多机 Kubernetes。
  10. 后续可扩展到更多模型转换后端。
  11. 后续可扩展为低代码模型转换产品。

3. 项目命名

推荐项目名:

ModelForge

中文名:

模型锻造平台

项目含义:

Model = 模型
Forge = 锻造、转换、优化、生成产物

推荐模块命名:

modelforge-api        后端 API 服务
modelforge-web        前端 Web 控制台
modelforge-core       任务和模板核心模块
modelforge-runner     通用任务运行器
modelforge-qnn        QNN 转换插件 / QNN Runner
modelforge-deploy     部署配置
modelforge-sdk        可选 Python SDK

推荐产品 Slogan

Upload. Convert. Optimize. Reproduce.

中文:

上传模型,一键转换,自动优化,全程可复现。

4. 总体架构

4.1 总体架构图

flowchart TD
    USER[普通用户 / 算法工程师] --> WEB[ModelForge Web]

    WEB --> API[ModelForge API]

    API --> PG[(PostgreSQL)]
    API --> MINIO[(MinIO)]
    API --> K3S[K3s API Server]

    API --> TEMPLATE[Template Engine]
    TEMPLATE --> MANIFEST[Task Manifest]
    TEMPLATE --> JOBYAML[Kubernetes Job YAML]

    API --> K3S
    K3S --> JOB[Kubernetes Job]
    JOB --> POD[Task Pod]
    POD --> RUNNER[ModelForge Runner Container]

    RUNNER --> MINIO
    API --> LOGWATCHER[Log / Pod Watcher]
    LOGWATCHER --> PG
    LOGWATCHER --> MINIO

    WEB --> TERMINAL[Web Terminal]
    TERMINAL --> API
    API --> EXEC[K8s Exec API]
    EXEC --> POD

5. 产品分层设计

ModelForge 采用五层产品架构。

┌────────────────────────────────────────────┐
│              Product Layer                 │
│  面向非专业用户的一键模型转换与优化页面        │
└────────────────────────────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────────┐
│              Template Layer                │
│  模型转换模板、优化模板、参数表单、任务预设      │
└────────────────────────────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────────┐
│              Task Layer                    │
│  任务创建、状态管理、事件流、日志、产物、复现     │
└────────────────────────────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────────┐
│              Execution Layer               │
│  K3s、Kubernetes Job、Pod、Container、Exec   │
└────────────────────────────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────────┐
│              Artifact Layer                │
│  MinIO输入、输出、日志、Manifest、报告        │
└────────────────────────────────────────────┘

6. 用户视角分层

6.1 普通模式

普通模式面向非专业用户。

用户页面只暴露必要参数:

上传模型
选择模型来源格式
选择目标平台
选择目标芯片
选择精度模式
选择优化等级
开始转换
查看进度
下载结果
查看报告

普通用户不需要看到:

镜像
命令
参数
环境变量
K8s Job
Pod
Manifest
MinIO 路径

6.2 高级模式

高级模式面向算法工程师、平台工程师。

高级模式可以查看和配置:

容器镜像
镜像 digest
执行命令
执行参数
环境变量
资源限制
任务 Manifest
Kubernetes Job YAML
Pod YAML
实时日志
输入输出文件
调试终端
任务事件流

7. 核心领域模型

平台不要只围绕 Task 设计,而应该围绕以下核心对象设计:

Project
Model
Template
Task
Artifact
Report
DebugSession

7.1 Project

Project 表示一个用户项目。

例如:

手机端目标检测模型优化
车载感知模型 QNN 转换
边缘设备模型加速项目

一个 Project 下可以有多个 Model。


7.2 Model

Model 表示用户上传的模型资产。

核心字段:

model_id
project_id
model_name
source_format
framework
input_shape
opset_version
file_uri
checksum
created_at

Model 是后续转换、优化、验证任务的基础输入。


7.3 Template

Template 表示一种任务模板。

例如:

QNN 标准转换模板
QNN INT8 量化模板
TensorRT FP16 优化模板
ONNX Simplify 模板
Benchmark 模板
Accuracy Check 模板

Template 是平台最重要的扩展点。

新增一种模型转换能力时,优先通过新增 Template 实现,而不是修改核心任务系统。


7.4 Task

Task 表示一次具体执行记录。

一个 Task 可以来自某个 Template也可以来自高级模式下的自定义任务。

核心字段:

task_id
project_id
model_id
template_id
task_type
status
manifest_uri
input_prefix
output_prefix
log_prefix
created_at
started_at
finished_at

7.5 Artifact

Artifact 表示任务输入、输出、日志、报告等文件。

Artifact 类型包括:

input_model
input_config
output_model
output_package
stdout_log
stderr_log
manifest
job_yaml
pod_yaml
report
debug_record

7.6 Report

Report 表示任务生成的结构化报告。

例如:

转换结果
模型输入输出信息
算子支持情况
优化策略
性能结果
转换日志摘要
错误原因
推荐修复方式

7.7 DebugSession

DebugSession 表示一次调试会话。

用于记录:

调试用户
调试开始时间
调试结束时间
目标 Pod
目标容器
调试命令记录
调试会话日志

8. 推荐技术选型

8.1 总体技术栈

模块 技术选型 说明
前端 React + Ant Design / Vue3 + Naive UI 管理后台和产品页面均适合
后端 FastAPI Python 生态友好,适合模型平台
数据库 PostgreSQL 保存任务状态、事件、索引、配置
对象存储 MinIO 保存输入、输出、日志、Manifest、报告
容器编排 K3s 单机轻量 Kubernetes
任务执行 Kubernetes Job 每个任务对应一个 Job
调试能力 K8s exec + WebSocket Terminal 支持进入运行中容器
临时调试容器 Ephemeral Container可选 镜像缺调试工具时使用
镜像仓库 Harbor / Docker Registry 保存 Runner 镜像
API 文档 OpenAPI / Swagger 前后端对接
鉴权 JWT 简单实用
部署 Helm / Kustomize 便于后续维护
模板渲染 Jinja2 / Jsonnet 渲染 Job YAML 和命令参数
日志存储 MinIO + PgSQL 索引 大日志不进数据库

9. 为什么选择 K3s

当前平台是单机平台,但任务形态已经接近批处理容器平台。

如果直接使用 Docker Engine需要自行实现

任务生命周期管理
容器状态追踪
资源限制
任务取消
任务超时
日志采集
容器重试
任务隔离
后续多机迁移
GPU 调度

使用 K3s 后,上述能力大部分由 Kubernetes 提供。

K3s 适合当前场景的原因:

轻量
单机可部署
兼容 Kubernetes API
支持 Job
支持资源限制
支持 namespace
支持 Secret
支持 ConfigMap
支持 ServiceAccount
支持后续平滑迁移到标准 Kubernetes

因此,第一版执行层建议使用:

K3s + Kubernetes Job

而不是:

Docker Engine + 自研调度器

10. 任务执行架构

10.1 执行模型

每个模型转换任务对应一个 Kubernetes Job。

Task
  -> Task Manifest
  -> Job YAML
  -> Kubernetes Job
  -> Pod
  -> Runner Container

10.2 任务执行流程

sequenceDiagram
    participant User as 用户
    participant Web as Web 页面
    participant API as ModelForge API
    participant PG as PostgreSQL
    participant S3 as MinIO
    participant K3s as K3s
    participant Pod as Runner Pod

    User->>Web: 创建转换任务
    Web->>API: 提交模型和转换参数
    API->>PG: 创建 Task
    API->>S3: 保存输入文件
    API->>S3: 保存 Task Manifest
    API->>S3: 保存 Job YAML
    API->>K3s: 创建 Kubernetes Job
    K3s->>Pod: 启动 Runner 容器
    Pod->>S3: 下载输入文件
    Pod->>Pod: 执行模型转换 / 优化
    Pod->>S3: 上传输出文件和报告
    API->>K3s: 监听 Pod / Job 状态
    API->>S3: 保存 stdout / stderr
    API->>PG: 更新 Task 状态
    Web->>API: 查询结果
    API->>Web: 返回产物和报告

11. Task Manifest 设计

Task Manifest 是任务可复现的核心。

每个任务创建后生成一份不可变 Manifest。

Manifest 保存:

任务 ID
任务类型
模型信息
输入文件 URI
输入文件 checksum
执行镜像
镜像 digest
执行命令
执行参数
环境变量
资源配置
模板版本
Runner 版本
输出路径
调试配置
创建时间
创建用户

示例:

apiVersion: modelforge/v1
kind: ModelTask
metadata:
  task_id: "task-20260605-000001"
  project_id: "project-001"
  model_id: "model-001"
  created_by: "user-a"
  created_at: "2026-06-05T10:00:00+09:00"

spec:
  task_type: "qnn_convert"
  template_id: "qnn_convert_default"
  template_version: "1.0.0"

  model:
    name: "resnet50.onnx"
    source_format: "onnx"
    uri: "s3://modelforge/tasks/task-20260605-000001/input/resnet50.onnx"
    checksum: "sha256:xxxx"

  runner:
    image: "registry.local/modelforge-qnn:1.0.0"
    image_digest: "sha256:xxxx"
    command:
      - "python"
      - "/app/run.py"
    args:
      - "--input=/workspace/input/resnet50.onnx"
      - "--output=/workspace/output"
      - "--target=qnn"
      - "--precision=fp16"

  resources:
    cpu: "8"
    memory: "32Gi"
    gpu: 0

  artifact:
    bucket: "modelforge"
    task_prefix: "tasks/task-20260605-000001"
    input_prefix: "tasks/task-20260605-000001/input"
    output_prefix: "tasks/task-20260605-000001/output"
    log_prefix: "tasks/task-20260605-000001/logs"

  debug:
    enabled: false
    keep_alive_on_failure: true
    shell: "/bin/bash"

12. Template 设计

Template 是平台扩展的核心。

新增一种能力时,优先新增 Template而不是改核心代码。

12.1 Template 组成

一个 Template 包含:

基础信息
用户表单 Schema
参数校验规则
Runner 镜像
命令模板
参数模板
资源默认值
输出产物规则
报告解析规则

12.2 Template 示例

template_id: qnn_convert_default
name: QNN 标准转换
category: qnn
version: 1.0.0

ui_schema:
  fields:
    - name: target_chip
      label: 目标芯片
      type: select
      required: true
      options:
        - SA8295
        - SA8650
        - SM8650

    - name: precision
      label: 精度模式
      type: select
      required: true
      options:
        - FP16
        - INT8

    - name: optimization_level
      label: 优化等级
      type: select
      required: true
      options:
        - fast
        - balanced
        - max

runner:
  image: registry.local/modelforge-qnn:1.0.0
  command:
    - python
    - /app/run.py
  args_template:
    - "--target-chip={{ target_chip }}"
    - "--precision={{ precision }}"
    - "--optimization-level={{ optimization_level }}"

resources:
  default:
    cpu: "4"
    memory: "16Gi"
    gpu: 0
  max:
    cpu: "16"
    memory: "64Gi"
    gpu: 1

outputs:
  - name: qnn_package
    path: /workspace/output
    type: directory
  - name: report
    path: /workspace/output/report.json
    type: file

13. Runner 设计

Runner 是实际运行在容器中的执行程序。

Runner 负责:

读取 Task Manifest
从 MinIO 下载输入
准备 workspace
执行转换命令
捕获 stdout/stderr
保存输出文件
生成 report.json
上传输出到 MinIO
返回标准 exit code
支持 debug keep-alive

13.1 Runner 执行流程

启动容器
  -> 读取 manifest
  -> 下载 input
  -> 创建 workspace
  -> 执行转换
  -> 收集 output
  -> 生成 report
  -> 上传 output/report/logs
  -> 退出

13.2 Runner 目录约定

/workspace/
  input/
    model.onnx
    config.yaml
  output/
    model.so
    context.bin
    report.json
  logs/
    stdout.log
    stderr.log
  tmp/

13.3 Runner 返回码约定

0    成功
10   输入文件错误
11   参数错误
20   模型格式不支持
21   算子不支持
30   QNN 转换失败
31   量化失败
40   输出上传失败
50   系统异常

14. 调试模式设计

14.1 调试能力分层

调试能力分为三层:

K8s exec
Ephemeral Container
Debug Sidecar

14.2 K8s exec

第一阶段优先实现 K8s exec。

用于进入正在运行的主容器:

Web Terminal
  -> ModelForge API
  -> K8s exec websocket
  -> Runner Container

适合:

查看文件
执行 shell
查看中间产物
手动运行命令
排查转换失败原因

14.3 失败后保活

第一阶段推荐使用失败后保活策略。

当任务失败且开启 debug 模式时Runner 不立即退出,而是保持容器运行。

python /app/run.py
EXIT_CODE=$?

if [ "$DEBUG_KEEP_ALIVE" = "true" ] && [ "$EXIT_CODE" != "0" ]; then
    echo "Task failed, keep container alive for debugging"
    sleep infinity
fi

exit $EXIT_CODE

这样平台可以通过 Web Terminal 进入容器调试。


14.4 Ephemeral Container

第二阶段可支持 Ephemeral Container。

适合主镜像过于精简,没有 bash、curl、strace 等工具时使用。

Pod
  - runner container
  - ephemeral debug container

14.5 Debug Sidecar

Sidecar 不作为默认调试方案,只在需要常驻调试代理时使用。

适合:

文件浏览 agent
Web shell agent
metrics exporter
artifact syncer
debug proxy

不建议所有任务默认注入 sidecar避免增加资源开销和安全风险。


15. MinIO 存储设计

15.1 Bucket 设计

建议使用一个主 bucket

modelforge

目录结构:

modelforge/
  projects/
    {project_id}/
      models/
        {model_id}/
          original/
          metadata.json

  tasks/
    {task_id}/
      manifest/
        task_manifest.yaml
        job.yaml
        pod.yaml
        image_info.json

      input/
        model.onnx
        config.yaml
        calibration_data/

      output/
        converted_model/
        package.zip
        report.json

      logs/
        stdout.log
        stderr.log
        events.jsonl

      debug/
        sessions/
          session_001.json

      metadata/
        env.json
        command.json
        resources.json

15.2 存储原则

输入文件不可变
Manifest 不可变
Job YAML 必须保存
Pod YAML 必须保存
stdout/stderr 存 MinIO
PgSQL 只保存日志 URI
产物按 task_id 隔离
报告结构化保存
大文件不进数据库

16. PostgreSQL 数据模型

16.1 projects

CREATE TABLE projects (
    id UUID PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    created_by VARCHAR(128),
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.2 models

CREATE TABLE models (
    id UUID PRIMARY KEY,
    project_id UUID REFERENCES projects(id),
    name VARCHAR(255) NOT NULL,
    source_format VARCHAR(64),
    framework VARCHAR(64),
    input_shape JSONB,
    metadata JSONB,
    file_uri TEXT NOT NULL,
    checksum VARCHAR(128),
    created_by VARCHAR(128),
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.3 task_templates

CREATE TABLE task_templates (
    id UUID PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    category VARCHAR(64),
    version VARCHAR(64),
    description TEXT,

    ui_schema JSONB,
    runner_spec JSONB,
    resource_spec JSONB,
    output_spec JSONB,

    enabled BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.4 tasks

CREATE TABLE tasks (
    id UUID PRIMARY KEY,
    project_id UUID REFERENCES projects(id),
    model_id UUID REFERENCES models(id),
    template_id UUID REFERENCES task_templates(id),

    name VARCHAR(255) NOT NULL,
    task_type VARCHAR(64) NOT NULL,
    status VARCHAR(32) NOT NULL,

    image VARCHAR(512),
    image_digest VARCHAR(256),
    command JSONB,
    args JSONB,
    env JSONB,
    resources JSONB,

    manifest_uri TEXT,
    job_yaml_uri TEXT,
    pod_yaml_uri TEXT,

    input_prefix TEXT,
    output_prefix TEXT,
    log_prefix TEXT,

    k8s_namespace VARCHAR(128),
    k8s_job_name VARCHAR(255),
    k8s_pod_name VARCHAR(255),

    exit_code INTEGER,
    error_message TEXT,

    debug_enabled BOOLEAN DEFAULT FALSE,
    keep_alive_on_failure BOOLEAN DEFAULT FALSE,

    created_by VARCHAR(128),
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    submitted_at TIMESTAMP,
    started_at TIMESTAMP,
    finished_at TIMESTAMP,
    updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.5 task_events

CREATE TABLE task_events (
    id BIGSERIAL PRIMARY KEY,
    task_id UUID REFERENCES tasks(id),
    event_type VARCHAR(64) NOT NULL,
    level VARCHAR(16) DEFAULT 'INFO',
    message TEXT,
    payload JSONB,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.6 artifacts

CREATE TABLE artifacts (
    id BIGSERIAL PRIMARY KEY,
    task_id UUID REFERENCES tasks(id),
    model_id UUID REFERENCES models(id),
    artifact_type VARCHAR(64) NOT NULL,
    name VARCHAR(255),
    uri TEXT NOT NULL,
    size_bytes BIGINT,
    checksum VARCHAR(128),
    metadata JSONB,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.7 reports

CREATE TABLE reports (
    id UUID PRIMARY KEY,
    task_id UUID REFERENCES tasks(id),
    report_type VARCHAR(64),
    report_uri TEXT,
    summary JSONB,
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

16.8 debug_sessions

CREATE TABLE debug_sessions (
    id UUID PRIMARY KEY,
    task_id UUID REFERENCES tasks(id),
    user_id VARCHAR(128),
    pod_name VARCHAR(255),
    container_name VARCHAR(255),
    status VARCHAR(32),
    started_at TIMESTAMP NOT NULL DEFAULT NOW(),
    ended_at TIMESTAMP,
    transcript_uri TEXT
);

17. 任务状态机

stateDiagram-v2
    [*] --> CREATED
    CREATED --> UPLOADING
    UPLOADING --> READY
    READY --> SUBMITTED
    SUBMITTED --> SCHEDULING
    SCHEDULING --> RUNNING
    RUNNING --> SUCCEEDED
    RUNNING --> FAILED
    RUNNING --> CANCELLING
    CANCELLING --> CANCELLED
    FAILED --> DEBUGGING
    DEBUGGING --> FAILED
    FAILED --> RETRYING
    RETRYING --> SUBMITTED
    SUCCEEDED --> [*]
    CANCELLED --> [*]

状态说明:

状态 含义
CREATED 任务已创建
UPLOADING 输入文件上传中
READY 输入和配置已准备好
SUBMITTED 已提交到 K3s
SCHEDULING Pod 调度中
RUNNING 容器运行中
SUCCEEDED 成功
FAILED 失败
DEBUGGING 调试中
RETRYING 重试中
CANCELLING 取消中
CANCELLED 已取消

18. 后端架构设计

18.1 后端目录结构

backend/
  app/
    api/
      routes_projects.py
      routes_models.py
      routes_tasks.py
      routes_templates.py
      routes_artifacts.py
      routes_reports.py
      routes_logs.py
      routes_debug.py

    core/
      config.py
      security.py
      errors.py

    db/
      session.py
      models.py
      repositories.py

    services/
      project_service.py
      model_service.py
      task_service.py
      template_service.py
      manifest_service.py
      minio_service.py
      k8s_service.py
      log_service.py
      artifact_service.py
      report_service.py
      debug_service.py

    workers/
      k8s_watcher.py
      log_collector.py
      artifact_scanner.py

    schemas/
      project.py
      model.py
      task.py
      template.py
      artifact.py
      report.py
      debug.py

    main.py

18.2 后端核心服务

ProjectService
  管理项目

ModelService
  管理模型资产

TemplateService
  管理任务模板和 UI schema

TaskService
  管理任务生命周期

ManifestService
  生成和保存 Task Manifest

K8sService
  渲染 Job YAML、提交 Job、取消 Job、查询 Pod

MinioService
  上传、下载、生成预签名 URL

LogService
  采集和查询日志

ArtifactService
  扫描和登记产物

ReportService
  解析和展示报告

DebugService
  管理 exec、terminal、debug session

19. 前端架构设计

19.1 前端页面

普通用户页面:
  - 项目列表
  - 项目详情
  - 模型上传
  - 一键转换
  - 转换进度
  - 结果下载
  - 报告查看

高级用户页面:
  - 任务列表
  - 任务详情
  - 模板管理
  - Manifest 查看
  - Job YAML 查看
  - Pod YAML 查看
  - 实时日志
  - Web Terminal
  - Artifact Browser

19.2 前端目录结构

frontend/
  src/
    pages/
      Projects/
      Models/
      ConvertWizard/
      TaskList/
      TaskDetail/
      TemplateManager/
      ArtifactBrowser/
      Reports/
      DebugTerminal/

    components/
      ModelUploader/
      TemplateForm/
      TaskStatusTag/
      TaskTimeline/
      LogViewer/
      WebTerminal/
      ArtifactTable/
      ReportViewer/
      ManifestViewer/
      YamlViewer/

    api/
      projectApi.ts
      modelApi.ts
      taskApi.ts
      templateApi.ts
      artifactApi.ts
      reportApi.ts
      debugApi.ts

    stores/
      projectStore.ts
      modelStore.ts
      taskStore.ts
      userStore.ts

20. 前后端接口设计

20.1 接口风格

采用:

REST API + WebSocket

REST API 用于:

项目管理
模型管理
模板管理
任务创建
任务查询
产物查询
报告查询
任务取消
任务重试
任务克隆

WebSocket 用于:

实时日志
Web Terminal
任务状态推送

统一 API 前缀:

/api/v1

20.2 Project API

GET    /api/v1/projects
POST   /api/v1/projects
GET    /api/v1/projects/{project_id}
PUT    /api/v1/projects/{project_id}
DELETE /api/v1/projects/{project_id}

20.3 Model API

GET    /api/v1/projects/{project_id}/models
POST   /api/v1/projects/{project_id}/models
GET    /api/v1/models/{model_id}
DELETE /api/v1/models/{model_id}

上传模型:

POST /api/v1/projects/{project_id}/models/upload
Content-Type: multipart/form-data

20.4 Template API

GET    /api/v1/templates
POST   /api/v1/templates
GET    /api/v1/templates/{template_id}
PUT    /api/v1/templates/{template_id}
DELETE /api/v1/templates/{template_id}

获取模板表单 schema

GET /api/v1/templates/{template_id}/ui-schema

20.5 Task API

创建任务:

POST /api/v1/tasks

Request:

{
  "project_id": "project-001",
  "model_id": "model-001",
  "template_id": "qnn_convert_default",
  "name": "resnet50-qnn-fp16",
  "params": {
    "target_chip": "SA8650",
    "precision": "FP16",
    "optimization_level": "balanced"
  },
  "debug": {
    "enabled": true,
    "keep_alive_on_failure": true
  }
}

Response:

{
  "task_id": "task-20260605-000001",
  "status": "CREATED"
}

提交任务:

POST /api/v1/tasks/{task_id}/submit

查询任务:

GET /api/v1/tasks/{task_id}

查询任务事件:

GET /api/v1/tasks/{task_id}/events

取消任务:

POST /api/v1/tasks/{task_id}/cancel

重试任务:

POST /api/v1/tasks/{task_id}/retry

克隆任务:

POST /api/v1/tasks/{task_id}/clone

20.6 Artifact API

GET /api/v1/tasks/{task_id}/artifacts
GET /api/v1/artifacts/{artifact_id}/download

返回示例:

{
  "artifacts": [
    {
      "id": 1,
      "name": "package.zip",
      "artifact_type": "output_package",
      "size_bytes": 1024000,
      "download_url": "https://..."
    }
  ]
}

20.7 Report API

GET /api/v1/tasks/{task_id}/report

返回示例:

{
  "task_id": "task-001",
  "status": "SUCCEEDED",
  "summary": {
    "source_format": "onnx",
    "target_format": "qnn",
    "precision": "FP16",
    "output_files": 3,
    "warnings": 1
  }
}

20.8 Log API

获取完整日志:

GET /api/v1/tasks/{task_id}/logs?stream=stdout

实时日志:

WS /api/v1/tasks/{task_id}/logs/ws

WebSocket 消息:

{
  "timestamp": "2026-06-05T10:00:00+09:00",
  "stream": "stdout",
  "line": "Start model conversion..."
}

20.9 Debug API

开启调试:

POST /api/v1/tasks/{task_id}/debug/enable

关闭调试:

POST /api/v1/tasks/{task_id}/debug/disable

Web Terminal

WS /api/v1/tasks/{task_id}/terminal

前端发送:

{
  "type": "stdin",
  "data": "ls -lah\n"
}

后端返回:

{
  "type": "stdout",
  "data": "total 12K\n"
}

21. Kubernetes Job 模板

apiVersion: batch/v1
kind: Job
metadata:
  name: modelforge-task-${TASK_ID}
  namespace: modelforge
  labels:
    app: modelforge
    task_id: "${TASK_ID}"
    task_type: "${TASK_TYPE}"
spec:
  backoffLimit: 0
  activeDeadlineSeconds: 7200
  ttlSecondsAfterFinished: 86400
  template:
    metadata:
      labels:
        app: modelforge
        task_id: "${TASK_ID}"
    spec:
      restartPolicy: Never
      serviceAccountName: modelforge-runner
      containers:
        - name: runner
          image: "${IMAGE}"
          imagePullPolicy: IfNotPresent
          command:
            - "python"
            - "/app/runner.py"
          args:
            - "--manifest"
            - "s3://modelforge/tasks/${TASK_ID}/manifest/task_manifest.yaml"
          env:
            - name: TASK_ID
              value: "${TASK_ID}"
            - name: DEBUG_KEEP_ALIVE
              value: "${DEBUG_KEEP_ALIVE}"
            - name: S3_ENDPOINT
              valueFrom:
                secretKeyRef:
                  name: minio-secret
                  key: endpoint
            - name: S3_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: minio-secret
                  key: access_key
            - name: S3_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: minio-secret
                  key: secret_key
          resources:
            requests:
              cpu: "${CPU_REQUEST}"
              memory: "${MEMORY_REQUEST}"
            limits:
              cpu: "${CPU_LIMIT}"
              memory: "${MEMORY_LIMIT}"
          volumeMounts:
            - name: workspace
              mountPath: /workspace
      volumes:
        - name: workspace
          emptyDir: {}

22. 网络架构

flowchart LR
    USER[用户浏览器] -->|HTTPS 443| INGRESS[Ingress / Nginx]

    INGRESS -->|HTTP 3000| WEB[ModelForge Web]
    INGRESS -->|HTTP 8000| API[ModelForge API]

    API -->|5432| PG[(PostgreSQL)]
    API -->|9000| MINIO[(MinIO)]
    API -->|6443| K3S[K3s API Server]

    K3S --> POD[Task Pod]
    POD -->|9000| MINIO
    POD -->|443/5000| REGISTRY[Image Registry]

    USER -->|WebSocket 443| INGRESS
    INGRESS --> API
    API -->|K8s exec websocket| K3S
    K3S --> POD

端口规划:

服务 端口 暴露范围
Web 80 / 443 用户
API 8000 Ingress 内部
PostgreSQL 5432 集群内部
MinIO API 9000 集群内部,可选外部
MinIO Console 9001 管理员
K3s API 6443 后端访问
Registry 5000 / 443 集群内部
WebSocket Terminal 443 用户通过 Ingress 访问

23. 部署架构

单机部署建议:

一台服务器
  - K3s
  - ModelForge API
  - ModelForge Web
  - PostgreSQL
  - MinIO
  - Image Registry
  - QNN Runner Job

部署方式:

K3s 安装脚本
Helm / Kustomize 部署平台组件
Namespace 隔离
Secret 管理 MinIO 凭证
ServiceAccount 控制 Runner 权限
Ingress 暴露 Web 和 API

Namespace 建议:

modelforge-system     平台服务
modelforge-tasks      任务 Job
modelforge-storage    MinIO / PostgreSQL可选

24. 可扩展设计

24.1 模型后端扩展

后续可以通过新增 Template 和 Runner 镜像扩展:

QNN
TensorRT
OpenVINO
TFLite
NCNN
ONNX Runtime
TVM

核心平台不需要感知具体转换逻辑。


24.2 Pipeline 扩展

第一阶段 Task 可以是单步骤任务。

后续可扩展为线性 Pipeline

模型检查
  -> 模型转换
  -> 模型优化
  -> Benchmark
  -> 报告生成

再后续可接入 Argo Workflows实现复杂 DAG。

但第一版不建议直接上 Argo避免复杂度过高。


24.3 UI 扩展

通过 Template 的 ui_schema 自动生成表单。

新增模板时,前端不需要硬编码页面。

普通用户看到的是模板表单:

目标芯片
精度模式
优化等级
输入 shape
是否量化

后端根据模板生成:

Task Manifest
Job YAML
Runner 参数
输出规则
报告解析规则

24.4 执行层扩展

第一阶段:

K3s Job Executor

后续可以扩展:

Kubernetes Job Executor
Argo Workflow Executor
Docker Executor
Remote Cluster Executor

建议定义统一执行接口:

class Executor:
    def submit(task_manifest): ...
    def cancel(task_id): ...
    def get_status(task_id): ...
    def get_logs(task_id): ...
    def exec(task_id, command): ...

25. 系统复杂度控制原则

第一版只保留必要核心能力:

Project
Model
Template
Task
Artifact
Report
Debug

不要一开始引入:

复杂 DAG
多租户资源配额
完整 MLOps 模型注册中心
在线推理服务
多集群调度
复杂审批流
复杂 RBAC
Argo Workflows
Prometheus 全量监控体系

第一版核心闭环:

上传模型
  -> 选择模板
  -> 生成任务
  -> K3s Job 执行
  -> 保存日志
  -> 保存产物
  -> 生成报告
  -> 支持调试
  -> 支持复现

26. 最终推荐架构

最终推荐第一版架构:

ModelForge Web
ModelForge API
PostgreSQL
MinIO
K3s
Kubernetes Job
ModelForge Runner

产品抽象:

Project
Model
Template
Task
Artifact
Report

技术抽象:

Task Manifest
Job Renderer
Runner
Executor
Artifact Store
Debug Session

核心原则:

用户使用产品能力;
平台维护任务模板;
K3s 负责容器生命周期;
MinIO 负责文件留痕;
PostgreSQL 负责状态和索引;
Task Manifest 负责可复现;
Runner 负责具体模型转换;
Template 负责后续扩展。

该架构既能满足当前单机 QNN 转换平台需求,也能为后续非专业用户的一键模型转换与优化系统留下足够扩展空间。


15. Argo Workflows 集成(扩展架构)

15.1 概述

为了提升流水线的可扩展性、可观测性和并行能力ModelForge 新增 Argo Workflows 作为 第二执行引擎。与原有的单 Pod 多 InitContainer 方案不同Argo 模式下流水线的每个步骤 都运行在独立的 Pod 中,形成 DAG有向无环图工作流。

15.2 架构对比

维度 原有 K8s Job 模式 Argo Workflows 模式
执行单元 单 Pod + InitContainer + Sidecar 多 Pod DAG
并行度 串行 并行 + 串行混合
重试策略 整个 Job 重试 按步骤独立重试
资源分配 Pod 级别统一 按步骤独立 CPU/内存
可观测性 kubectl logs Argo UI + CLI + Grafana
产物传递 EmptyDir 共享卷 卷 + S3 混合
扩展新步骤 修改模板 YAML + 镜像 新增 DAG 节点 + 镜像

15.3 流水线步骤

sync-input (MinIO 下载)
    ├── quant-prep (量化数据预处理)
    └── onnx-optimize (ONNX 优化简化)
            └── qnn-convert (QNN 转换 → lib.so)
                    ├── generate-ctx (生成 HTP ctx.bin)
                    ├── upload-outputs (产物上传 MinIO)
                    └── precision-analysis (精度分析)

15.4 快速试用

# 1. 切换到 Argo 分支
git checkout feature/argo-workflow

# 2. 安装 Argo Workflows
bash argo/install.sh

# 3. 构建新镜像
bash docker/build-argo-images.sh

# 4. 通过 CLI 提交流水线
bash argo/submit-workflow.sh \
    --model "projects/<pid>/models/<mid>/original/model.onnx" \
    --precision INT8 \
    --chip QCS8550

15.5 通过 API 使用

创建 Task 时指定 template_id: argo_qnn_pipeline,后端自动识别 template_mode: argo 并使用 ArgoExecutor 提交工作流。

详细文档见 argo/README.md