Skip to content

adapter check: read the LoRA's safetensors metadata, not just its filename (Realism People LoRA passes on ref2va) #870

Closed
1 of 1 issue completed

Description

@dkackman

What happened

The fal Realism People LoRA (fal/MiniMax-H3-Realism-People-LoRA, h3-realism-people-t2v-i2v-r2v.safetensors) was tried on a Ref2VA (transformer_ref) step to fix faces. It was inert - output indistinguishable from no LoRA - and cost a full render to find out.

dw/adapter_compatibility.py decides from the filename tokens ref2v / fl2v. This filename has neither (it says r2v), so validate only warns "names neither". The r2v actively suggests reference support.

The file's own header settles it: __metadata__ has base_model: minimax-h3-fl2va, training: text_to_video, rank 32. On FL2VA/I2VA it works (R3: 4/5 faces).

Proposal

  • When the weight file is local (or in the HF cache), read the safetensors __metadata__ (8-byte length + JSON, no tensor load) and prefer base_model over the filename. minimax-h3-fl2va on a ref2va step -> the same error the filename rule gives today.
  • Fall back to the filename rule when there's no metadata or the file isn't downloaded yet (or fetch just the header with a ranged GET on the Hub file).
  • Add the Realism LoRA to references/checkpoints-and-loras.md with "FL2VA/T2VA/I2VA only, not reference-to-video" spelled out.

Question

  • Other vendors' metadata keys differ (ss_base_model_version, modelspec.architecture). Map a few known keys, or only trust base_model?

Source: H3 quality matrix on lem (2x RTX 3090 24 GB, 125 GB host RAM), workspace h3-quality, Known Issues ep 6 shots, seed 42. Full data and per-run assessments: ~/testing/opus/known-issues/quality/matrix.json, report quality/REPORT.md; every run in h3-quality carries a note with its config, minutes and score. Related: #861 (follow-up experiments).

Activity

  1. added
    bugSomething isn't working
    enhancementNew feature or request
    ideaAn idea for the researcher agent to assess
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  2. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Plan v2: #870, a LoRA's partition from the catalog first, its filename second

    Lead design by claude-opus-5-5 (provider anthropic), 2026-10-13; v2 2026-10-14 after Don's ruling (a) on #888's stop.

    Verdict: build smaller

    The proposal reads the LoRA's safetensors header. The sweep found something better that already exists: the LoRA catalog already says which partition Realism People is for. loras/minimax-h3/realism-people.json has "workflow": "t2va" and "status": "proven". adapter_compatibility.py never looks at the catalog, though, so validate fell back to the filename and only warned. The plan wires the catalog into the check and leaves the header read out.

    • Value. The harm is a full H3 render lost to an adapter that loads silently onto the wrong partition: 10-40 min on lem, and nothing in the output says why. This time the "names neither" warning fired and the skill line ("never on a ref2va template") was there too, and the render still ran. A warning is not enough for this mistake. The class has come up before (Reference-conditioned H3 templates can drop 20 steps to 8: a Ref2VA turbo LoRA trained for transformer_ref now exists #149, validate_workflow accepts an FL2VA turbo LoRA on a ref2va step, the one H3 misconfiguration that never shows in the output #155). Today 30 H3 catalog entries exist, and 20 of them declare a partition. About 12 of those have names the filename rule can't settle: r2v, flf2v, or no token. The catalog settles them for free: proven entries by refusing, trial entries by a warning that names the entry.
    • Build cost. One stage, about $3-5.
    • Inertia.
      • No new MCP, REST or syntax surface, and no tool-description growth.
      • The cost is one new concept: the catalog's workflow field, on a proven entry, becomes something validate enforces, not just a ranking filter. docs/LORAS.md already describes it as a constraint ("constrains a MiniMax-H3 entry to a partition"), so the meaning doesn't change.
      • Validation gains an optional input that only the server can supply.
    • Reversibility. Fully reversible. Dropping the lookup brings back today's warning, and no names or data depend on it.
    • Cheaper alternatives.
      • Docs only: already done. The skill says "never on ref2va", and it didn't stop the render.
      • Catalog entry only: widening it to ["t2va","fl2va"] records the new evidence but enforces nothing. It is part of this stage.
    • Why the header read is cut:
      1. It is I/O on the hottest validation path. Validation runs on every validate, every admit, every for_each member and every composed child, and today that path is free and offline.
      2. A local-path model_name read during validate is a directory-existence oracle. plan.py:905 refuses exactly that.
      3. A ranged GET to the Hub contradicts "lora_hub.py is the only place dw searches the Hub" (docs/LORAS.md:173).
      4. __metadata__ is written by the uploader. Letting it turn a warning into a refusal trusts uncurated data.
      5. One vendor key (base_model) is the only evidence. The 10 catalog entries with workflow: null are the only ones a header could help, and nobody has checked whether they carry the key.
    • What would reopen the header read: a second render lost to a LoRA the catalog doesn't cover, or a run of trials of uncatalogued H3 LoRAs where the filename rule keeps saying "names neither". It would then go into save_lora / recommend_loras, which already read Hub headers through lora_hub.py:102, to pre-fill a catalog entry's workflow. The validator would stay free.
    • Overlap. None. H3 quality ramp: follow-up experiments (seed stability, cross-family composition lock, int4 base draft) #861, idea: quality-ramp skill - draft -> preview -> final tiers with measured cost/quality trade-offs (H3 first) #862 and feature: H3 templates - expose attention_backend + cache everywhere, and a quality tier preset that sets the coupled knobs together #865 are H3 quality and tier work and don't touch adapter checks.
    • Removal follow-up: none found.

    Problem and non-goals

    Problem. The H3 adapter check decides from ref2v / fl2v in weight_name. When a file name has neither token, the check only warns, even when the catalog states the adapter's partition.

    Non-goals:

    • reading safetensors headers;
    • any Hub request from validation;
    • non-H3 base-model checks;
    • changes to the filename rule itself;
    • per-workspace catalogs (v2: the catalog stays one shared library);
    • new evidence requirements on proven (v2: Don's ruling).

    Design

    1. Lookup. adapter_compatibility takes an optional catalog index: (model_name, weight_name) -> (entry name, workflows, status), built from the entries that declare a workflow. Revision is ignored (Q2). With no index, behavior is exactly today's.

    2. Partition, not workflow. A catalog entry decides the partition:

      • every listed workflow in {t2va, fl2va} means transformer;
      • ref2va means transformer_ref;
      • a list mixing both partitions decides nothing.

      So Realism People (t2va) is cleared on an fl2va step and conflicts on a ref2va step. This is the right granularity: the check guards partitions. Which workflows were tried is a ranking matter, and matches() keeps handling that.

    3. Order, and what the entry's status allows (v2):

      • proven entry that decides: its answer is used. A conflict with the step's partition is an error naming the entry as the source: "catalog entry minimax-h3/realism-people (proven) lists it for t2va, which denoises against transformer". Agreement clears the step with no "names neither" warning.
      • trial or rejected entry that decides: a conflict with the step's partition is a warning naming the entry and its status, never an error. Agreement clears the "names neither" warning (the entry is better evidence than nothing), but a filename-token error still stands. Only proven entries can refuse.
      • If the catalog doesn't cover the file, or its entry's workflow is null or mixed, the filename rule runs unchanged.
      • If a proven entry and a filename token disagree, it is a warning naming both, never an error (Q1). A filename-token error is kept only when no proven entry decides the other way.
    4. Who supplies the index (v2, rewritten). The catalog is one library shared by every workspace: server_lora_library(state) (dw/server/deps.py:386) is the server's writable loras/ then the examples' loras/, and takes no workspace (docs/LORAS.md:141). v1 assumed a per-workspace layer; there isn't one, and this plan doesn't add one. Only server callers pass the index:

      • /api/validate (and MCP validate_workflow);
      • submit and rerun admission;
      • save, and enhance-admit, in routes/library.py.

      It is built from the same catalog_entries(state) the list_loras route reads, cached per catalog listing the way ceiling_index is (deps.py:165), so the same answer holds in every workspace. The CLI dw.validate, the worker's sub-workflow re-validation and warn_adapters at run start pass none and keep today's rule. The server is therefore stricter than the worker, never looser. Nothing is refused at run time that admit let through.

    5. Cost. The index is built once per catalog listing (cached), and looked up per step; never rebuilt per step or per for_each member.

    6. Data and docs in the same stage:

      • realism-people.json: workflow becomes ["t2va","fl2va"], with an evidence note for the h3-quality matrix (R3, 4/5 faces on FL2VA/I2VA; the ref2va run inert). use_when says "not reference-to-video". It stays proven.
      • checkpoints-and-loras.md:28-33 (already rewritten by docs: minimax-h3 skill + RECIPES_24GB/ACCELERATION - base-model (no LoRA, int8) quality path and measured speed levers #863): change "validate warns the name fits neither partition" to "validate refuses it on ref2va".
      • Updated to the catalog-first rule: the module docstring, docs/ARCHITECTURE.md:105, docs/SERVER.md:368-375, and docs/LORAS.md (a proven entry's workflow is enforced by validate on the server; a trial entry's only warns; promoting to proven is what makes it refuse).

    Surfaces touched: engine (validation gains an optional input; a warning becomes an error for mismatches a proven catalog entry decides) and data/plugin docs. There is no MCP, REST or syntax change. This isn't breaking-change: the only workflows newly refused are ones a proven catalog entry says are misconfigured.

    Stages

    Stage A: catalog-backed adapter check (the whole feature)

    • Builds: everything in the design above, items 1-6.
    • Unit tests:
      • tests/test_h3_adapters.py:
        • a proven catalogued no-token file is an error on ref2va and clean on fl2va and t2va;
        • the same file under a trial (and a rejected) entry is a warning naming the entry on ref2va, not an error, and clean on fl2va;
        • no index gives the same "names neither" warning as today;
        • a null or mixed catalog workflow falls back to the filename rule;
        • a proven catalog entry that disagrees with the filename token is a warning, not an error;
        • a trial entry never lifts a filename-token error;
        • the arguments.<name> path is kept when the value came from a variable;
        • one index build per catalog listing, even for a for_each step.
      • The existing sweep of every workflows/**/*.json also runs with the packaged catalog and must stay error-free. That is what catches a template the new rule would break.
    • Docs: as listed in item 6.
    • Deploy: server (engine plus the loras/ data), restart on lem and mini-ai.
    • Estimate: $3-5.
    • Acceptance intent (over MCP):
      1. validate_workflow on an H3 ref2va step whose loras holds fal/MiniMax-H3-Realism-People-LoRA / h3-realism-people-t2v-i2v-r2v.safetensors:
        • the result is invalid, with an error at that entry's weight_name path;
        • the message names the transformer partition and the catalog entry;
        • run_workflow with the same workflow is refused before queueing, and no job is created.
      2. The same entry on a t2va or fl2va step validates with no adapter error and no "names neither" warning.
      3. A LoRA with no ref2v/fl2v token that no catalog entry covers still gets today's "names neither" warning on any H3 step and is not refused.
      4. The filename rule is unchanged for uncatalogued files: the FL2VA turbo file on a ref2va step is still an error, and a ref2v file on fl2va is still an error.
      5. When the weight name arrives through a variable the caller set, the error's path is arguments.<name>.
      6. list_loras shows minimax-h3/realism-people with workflow ["t2va","fl2va"], status: proven, and the new evidence.
      7. (v2, replaces v1's workspace layering.) A shipped trial entry that decides against the step only warns, naming the entry; it never refuses. Use entries already in the catalog, so nothing is written to the shared catalog:
        • minimax-h3/wushu-action-reference (trial, ["ref2va"], file wushu_h3_r2v_v7_2000.safetensors, no token) on a t2va step: valid, with a warning naming the entry and its trial status;
        • minimax-h3/better-human-motion (trial, ["t2va","fl2va"], no token) on a ref2va step: valid, with a warning naming the entry;
        • the same validate run with two different workspaces selected gives the same result (the catalog is shared).
      8. Every catalog template still validates clean (list_workflows plus validate_workflow over the H3 shapes).

    Order and dependencies

    The feature is a single stage with no blockers.

    Risks

    • A wrong catalog entry now refuses. Before, it only ranked badly. The catalog is shared and save_lora is agent-writable, so one careless entry would reach every workspace. v2 mitigates it this way:
      • only a proven entry can refuse; a trial or rejected entry that conflicts only warns, so a fresh trial can't block anyone;
      • promoting to proven is a deliberate act that already needs evidence (docs/LORAS.md:165);
      • the error names the entry, so the cause is visible and the fix is one save_lora;
      • a disagreement with a filename token is only a warning.
    • Server and CLI disagree: dw.validate on its own stays on the filename rule. This is documented, and it is the safe direction.
    • Hot-path cost, if the index were built per step. The tests pin one build per catalog listing.

    Questions

    Answered by Don on v1, unchanged: Q1 warn on a catalog/filename disagreement; Q2 ignore the revision; Q3 not needed (if a save_lora pre-fill comes back, base_model only). v2's status rule is Don's ruling (a) on #888's stop; no new questions.

    Reply in comments and hand back with owner:lead. Approve by adding status:plan-approved yourself. No agent may set it.

  3. added
    featureWork bigger than a fix: designed with Don, built in stages (harnest R11)
    owner:donParked for human decision
    status:plan-reviewA feature plan is posted and waiting for Don
    and removed
    ideaAn idea for the researcher agent to assess
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  4. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Review of plan v1: approve as written. Using the catalog instead of reading the safetensors header is the better design. The plan's figures were checked against current develop:

    • loras/minimax-h3/ has 30 entries, 20 of which declare a workflow and 10 are null.
    • realism-people.json already says "workflow": "t2va". adapter_compatibility.py just never asks the catalog.
    • No catalogued file name disagrees with its entry's workflow today. flf2v doesn't match the fl2v token, and the r2v/ref2va names all sit on ref2va entries. So the Q1 disagreement warning won't fire on anything shipped, and the planned sweep against the packaged catalog keeps it that way.

    Notes

    • The skill doc's Realism text is already half done. docs: minimax-h3 skill + RECIPES_24GB/ACCELERATION - base-model (no LoRA, int8) quality path and measured speed levers #863 (21a6f602) rewrote checkpoints-and-loras.md:28-33 to explain the header and say "inert on reference-to-video". This stage only needs to change "validate warns the name fits neither partition" to "validate refuses it on ref2va".
    • Turning the warning into an error is justified. The render ran even though both the warning and the skill line were in front of the agent, so only a refusal stops this mistake. Refusals stay limited to files the catalog covers.
    • For the tester: acceptance case 7 must confirm that the lookup follows the workspace the request selected, not the server's default or the last-used workspace.

    Questions: Q1 warn on a disagreement. Q2 ignore the revision. Q3 not needed; if the save_lora pre-fill comes back, use base_model only.

    claude-opus-5-5 / anthropic, for Don

  5. added
    owner:leadFeature lead's turn (harnest R11)
    status:plan-approvedDon approved the feature plan (Don only)
    and removed
    owner:donParked for human decision
    status:plan-reviewA feature plan is posted and waiting for Don
    on Oct 14, 2026
  6. 26 remaining items

  7. added
    status:needs-specTester writes acceptance cases for the plan's stages
    and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  8. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Spec for plan v2 by the tester (claude-opus-5-5 via anthropic). Before writing it I pinned today's catalog on lem with one read-only list_loras(model="MiniMaxAI/MiniMax-H3") call. No GPU time was spent.

    Stage #888 (reshaped). All cases are in regression-suite-model-specific.md and pending on #888.

    • New for v2:
      • M-F152 covers intent 7.
        • minimax-h3/wushu-action-reference on t2va/fl2va, and minimax-h3/better-human-motion on ref2va, are valid with a warning that names the entry and trial.
        • The same entries on their own partitions clear the "names neither" warning.
        • The template-variable route through reference-to-video is covered too.
        • It checks that the result is identical with the workspace pinned per call to two different workspaces and with the workspace selected by use_workspace.
      • M-F153 covers the status-gate edges.
        • Realism's refusal on ref2va names (proven).
        • A trial entry never downgrades a filename-token error: turbo-4step-reference (ref2v) on t2va, and wushu-action (fl2v) on ref2va, stay errors.
        • A string-workflow trial entry (360-orbit-loop, whose flf2v is not a token) on ref2va only warns.
    • Kept from v1: M-F142, M-F143, M-F144, M-F145 and M-F147 stand. M-F142's wording check still holds under v2. M-F153(a) adds the status requirement.
    • Dropped: M-F146 tested v1's workspace layering, and v2 contradicts it (its trial entry was expected to refuse). I filed suite: retire M-F146 (#870 plan v2 dropped workspace layering) harnest#122 (suite + status:needs-approval) to retire it.

    Notes, none blocking:

    1. Edges not observable over MCP without a catalog write. No shipped entry exercises any of the following:

      • a proven entry that disagrees with its own filename token (M-F144's Q1 edge as the lead re-scoped it);
      • a trial entry that agrees with the step while its token disagrees;
      • a mixed ["t2va","ref2va"] list;
      • a rejected entry with a non-null workflow (every rejected H3 entry is null).

      Probing any of these needs save_lora into the shared catalog, which has no removal route. So I left them to the plan's unit tests and didn't write a case that would leave stray entries behind.

    2. Admission of a trial conflict. M-F152 checks the trial-only-warns rule at validate time only. Showing that run_workflow admits it would queue a real H3 render, so the case doesn't do that. M-F142(c) already covers the refusal side of admission.

  9. added
    owner:leadFeature lead's turn (harnest R11)
    and removed
    status:needs-specTester writes acceptance cases for the plan's stages
    on Oct 14, 2026
  10. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    Close-out: feature built, handed to the tester for the final check. (lead, claude-opus-5-5 / anthropic)

    verify: run every case whose source: names one of this feature's stages, and close the parent if they all pass.

  11. added
    status:verifiedTester confirmed the fix via a real MCP call
    and removed
    owner:leadFeature lead's turn (harnest R11)
    on Oct 14, 2026
  12. dkackman commented on Oct 14, 2026

    @dkackman
    OwnerAuthor

    verify (tester, claude-opus-5-5 via anthropic, lem on develop @ 581bfff): every case whose source: names #888 passes. All were run over MCP this session.

    Catalog pins are unchanged. realism-people is still proven (t2va, fl2va). wushu-action-reference, better-human-motion and 360-orbit-loop are trial. turbo-keyframe and turbo-reference are proven.

    M-F145. The list_loras entry has the right shape. The fl2va and t2va filters include realism-people, and the ref2va filter excludes it.

    M-F142.

    • (a) An inline carrier with ref2va + realism is invalid at steps[0].pipeline.loras[0].weight_name. The message names the catalog entry minimax-h3/realism-people (proven), 't2va, fl2va' vs 'ref2va', and transformer_ref.
    • (b) The reference-to-video template with realism args gives the same error, at arguments.lora_weight_name.
    • (c) run_workflow with the same args and acknowledged_cost=true was refused with the same message and returned no job_id. list_jobs was unchanged (newest 5828e643e28d, total 200).

    M-F143 (a)–(d). All valid, with no adapter warnings.

    M-F144.

    • (a) ref2va + turbo fl2v 8step is invalid. It names minimax-h3/turbo-keyframe (proven) and transformer.
    • (b) fl2va + ref2v 8step is invalid. It names minimax-h3/turbo-reference (proven). The refusal cites the catalog entry rather than the bare filename rule. Either one is a refusal.
    • (c) An uncatalogued adapter on t2va is valid, with a "names neither" warning.
    • (d) A TaoMate adapter_model on ref2va is valid, with "names neither".
    • (e) A nonexistent repo + h3-realism-people… on ref2va is valid, with "names neither". It does not cite the realism entry.
    • (f) Adding "revision":"main" to the realism entry raises no schema error and gives the same proven-entry refusal.

    M-F152.

    • (a) C(t2va,W) and C(fl2va,W) are valid, each with a warning naming minimax-h3/wushu-action-reference (trial).
    • (b) C(ref2va,B) is valid, with a warning naming minimax-h3/better-human-motion (trial).
    • (c) C(ref2va,W), C(t2va,B) and C(fl2va,B) are valid, with only the seed and cost warnings.
    • (d) The reference-to-video template with B args is valid, with the trial warning at arguments.lora_weight_name.
    • (e) Results are identical in qa-c870-other, in regression-model-specific, and after use_workspace(qa-c870-other) with no workspace argument, with matching fingerprints. The scratch workspace has been deleted, and the session is back on regression-model-specific.

    M-F153.

    • (a) Covered by M-F142(a).
    • (b) C(t2va, ref2v_turbo_4step) and C(ref2va, wushu…fl2va…) are both invalid under the filename rule.
    • (c) C(ref2va, 360-Orbit flf2v) is valid, with a warning naming minimax-h3/360-orbit-loop (trial).

    M-F147. I ran validate_workflow on every H3 template from list_workflows(shape=shot|sequence). Templates that need media got asset:qa-cast/priya-portrait.jpg. The templates checked: chain-matched-and-aligned, chain-matched-to-audio, chain-video-continuity, chained-segments, composable-references, enhance-prompt, enhance-prompt-with-image, first-and-last-frame, generated-subject-reference, image-to-video, last-frame-only, reference-to-video, shots-batch, storyboard, video-with-audio, video-with-audio-768p, voice-timbre-reference, dialogue-short and music-video. All are valid: true, with no lora, weight_name or partition errors or warnings. The only warnings are the no-seed ones.

    Not run. M-F146 is still marked pending: #888, but plan v2 contradicts it: v2 makes trial entries warn-only. Its retire request is dkackman/harnest#122.

    No new regression case: the #888 cases already cover this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backend:cudabugSomething isn't workingenhancementNew feature or requestfeatureWork bigger than a fix: designed with Don, built in stages (harnest R11)owner:testerTester's turn to actstatus:plan-approvedDon approved the feature plan (Don only)status:verifiedTester confirmed the fix via a real MCP calltarget:lem

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions