Skip to content
helmstudio
Contents

h3 studio's manifest

h3 studio makes video with synchronised sound from MiniMax-H3, through a native Metal engine written in C behind a Go server: no Python, and no PyTorch. Its repository does not ship a manifest yet, so its registry entry carries one inline. Scored against the criteria, it passes six of the seven a manifest can answer; it declares no test profile.

The file is studios/h3-studio.yaml, shown in full. A note follows the line it explains.

# A registry entry: a pointer at h3 studio's repository
# (schema/registry-entry.json, docs/design/05-sdk-and-custom-studios.md §5a).
#
# The manifest belongs in the studio's own repository as helmstudio.yaml, beside
# the code it describes, so that a studio can announce a new build step without
# waiting for a helmstudio release. h3 studio does not ship one yet, so the
# manifest is carried inline here — and the pull request that moves `ref` to a
# commit where it does ship one deletes the inline copy, leaving one copy again.
#
# Where the inline manifest sets id, repo or ref, each must equal this entry's;
# the validator enforces it. There is no `certified` field: a level is derived
# from what has actually been checked, never declared by the thing being
# checked (docs/decisions.md M7 Q4, Q15).

id: h3-studio
The id the studio is known by everywhere, and the file is named for it.repo: https://github.com/janishar/h3c-studio
Where helmstudio clones from. It reads the repository with git, never through a forge's API.ref: a6eb54f3c9d8c3e711bab22574ec6599399a03f9
A full commit, not a branch, so what was reviewed is what installs.
manifest:
Inline, because the repository ships no helmstudio.yaml at this commit. Where it sets id, repo and ref, each must equal the pointer's, and the validator checks that they do.  id: h3-studio
The same id as the pointer's.  name: h3 studio
The name people see.  description: Native Metal video and audio generation from MiniMax-H3, no PyTorch in the loop.
One sentence saying what the studio does.  kinds: [video, audio]
What it makes: video with sound, so both kinds.  # 03 §2's identity hue, chosen against the yellow accent (docs/decisions.md M6 Q7).
  hue: { dark: "#e0a33c", light: "#a06a10" }
Its identity colour in each theme: a stripe, a dot and its clips on the timeline in the launcher, and the accent on its own page.  license: MIT
The studio's own licence. A weight has no licence field yet, so the model's licence is not declared anywhere in the manifest.  repo: https://github.com/janishar/h3c-studio
The same repository as the pointer's.  ref: a6eb54f3c9d8c3e711bab22574ec6599399a03f9
The same commit as the pointer's.  submodules: true
The engine, h3c, is a submodule, and the first build step runs inside it, so the clone fetches submodules too.  peak_ram_gb: 21 # docs/design/08-h3-dry-run.md and 01-prd.md §13; not re-measured. Added in M2 review round 1 with the human's approval.
What the model occupies once loaded. It is the number the arithmetic uses when another heavy studio is running; the comment says where it came from.  requires:
An Apple Silicon Mac with 64 GB of memory and 200 GB of disk, and the tools the build and the studio call, ffmpeg among them.    os: [darwin]
    arch: [arm64]
    tools: [git, make, cc, go, ffmpeg]
    ram_gb: 64
    disk_gb: 200
  runtime:
A native kernel on Metal, in C: the framework and the backends are separate fields because they make separate claims.    framework: native-kernel
    backends: [metal]
    precision: [bf16, int8]
    language: c
  capabilities: [kv, assets, gallery, timeline]
Settings and sessions, the files it makes, the gallery and the timeline: four sentences on the approval screen, and a token for exactly those.  network: [huggingface.co, cdn-lfs.huggingface.co]
The hosts it is expected to contact, for its weights.  storage:
A records collection for its takes, indexed on seed, model and session, with the prompt searchable, and caps on how many records and how many bytes of settings it may keep.    collections:
      - name: takes
        index: [seed, model, session]
        fts: [prompt]
    quota: { records: 100000, kv_bytes: 8388608 }
  sdk: { runtime: "^1", css: "^1" }
Pins major 1 of the runtime SDK and helm-css, which is what criterion 15 asks for.  build:
Two steps, in order: the Metal engine, built with make in its submodule, then the Go server.    - name: Build the Metal engine
      cwd: h3c
      run: make -j8
    - name: Build the studio server
      cwd: .
      run: go build -o dist/h3studio .
  # FL2VA and Ref2VA are two pipelines inside one MiniMaxAI/MiniMax-H3 repo,
  # both expected as subdirectories of the single directory h3studio's --model
  # flag points at (server/model.go: "FL2VA always, Ref2VA for references").
  # Both entries share dest so {models.fl2va} and {models.ref2va} resolve to
  # the same directory; files scopes them to their own subtree. This does not
  # reproduce the README's manual dedup-via-symlink trick (~66 GB instead of
  # ~196 GB) — the schema has no field for "these files are identical across
  # two weights, hardlink them" — see the report.
  weights:
Two pipelines from one Hugging Face repository, in one directory, each scoped to its own files. FL2VA is required; Ref2VA is optional, so install does not wait for its 134 GB.    - name: fl2va
      repo: MiniMaxAI/MiniMax-H3
      dest: MiniMax-H3
      files: ["FL2VA/**"]
      size_gb: 62
    - name: ref2va
      repo: MiniMaxAI/MiniMax-H3
      dest: MiniMax-H3
      files: ["Ref2VA/**"]
      size_gb: 134
      optional: true
  processes:
One process: the Go server, which drives the engine.    - name: studio
      role: main
      heavy: true
It holds the model, so only one heavy studio runs beside it: none.      cmd: "./dist/h3studio --h3 ./h3c/h3 --model {models.fl2va} --port {port} --root {data}"
{models.fl2va} becomes the real path of the weights directory, and {data} the data directory helmstudio keeps for the studio.      port: { prefer: 8710 }
      health: { tcp: true, timeout_s: 30, interval_s: 2 }
      # /api/queue does not answer the busy contract (M5 Q12), so the switch
      # dialog reads h3 as unknown until h3 serves one; move this path, and
      # `ref`, when it does.
      busy: { path: /api/queue }
Declared, so the switch dialog asks before stopping it. Until h3 serves the busy answer, the dialog reads it as unknown, never as idle.      ui: /