Commit Graph

18580 Commits

Author SHA1 Message Date
psychedelicious
99d3f16eb4 docs(mm): add reminder for self for field migrations 2025-10-13 10:30:07 +11:00
psychedelicious
01ca74e622 feat(mm): add sanity checks before probing paths 2025-10-13 10:30:07 +11:00
psychedelicious
25619684c0 fix(mm): clip vision identification 2025-10-13 10:30:07 +11:00
psychedelicious
d336aa45f5 feat(mm): more flexible config matching utils 2025-10-13 10:30:07 +11:00
psychedelicious
303acdb4ac fix(mm): sdxl ip adapter identification 2025-10-13 10:30:07 +11:00
psychedelicious
2e5ec1c98b fix(mm): t5 identification 2025-10-13 10:30:07 +11:00
psychedelicious
56e31ca4ac fix(mm): ensure unknown model configs get unknown attrs 2025-10-13 10:30:07 +11:00
psychedelicious
74e4dd4393 docs(mm): remove extraneous comment 2025-10-13 10:30:07 +11:00
psychedelicious
233b286893 feat(mm): satisfy type checker in flux denoise 2025-10-13 10:30:07 +11:00
psychedelicious
07a667ad9f feat(mm): add helper method for legacy configs 2025-10-13 10:30:07 +11:00
psychedelicious
7437a14301 docs(mm): document flux variant attr 2025-10-13 10:30:07 +11:00
psychedelicious
09fef01786 docs(mm): update docsstrings in factory.py 2025-10-13 10:30:07 +11:00
psychedelicious
83fe40e7ee fix(mm): inverted condition 2025-10-13 10:30:07 +11:00
psychedelicious
13b2f9d12b refactor(mm): remove legacy probe, new configs dir structure, update imports 2025-10-13 10:30:07 +11:00
psychedelicious
0214afc3d1 chore(ui): typegen 2025-10-13 10:30:07 +11:00
psychedelicious
e23ac6d813 docs(mm): add comments for identification utils 2025-10-13 10:30:07 +11:00
psychedelicious
9faffe93f9 refactor(mm): split configs into separate files 2025-10-13 10:30:07 +11:00
psychedelicious
edfd90f2a4 tidy(mm): consistent class names 2025-10-13 10:30:06 +11:00
psychedelicious
e48e354bf1 fix(mm): tag generation & scattered probe fixes 2025-10-13 10:30:06 +11:00
psychedelicious
4ded5b5a80 feat(mm): consistent naming for all model config classes 2025-10-13 10:30:06 +11:00
psychedelicious
ee5808355d refactor(mm): diffusers loras
w
2025-10-13 10:30:06 +11:00
psychedelicious
af305250cb refactor(mm): make config classes narrow
Simpler logic to identify, less complexity to add new model, fewer
useless attrs that do not relate to the model arch, etc
2025-10-13 10:30:06 +11:00
psychedelicious
c065655a1d tidy(mm): flux lora format util 2025-10-13 10:30:06 +11:00
psychedelicious
a0a4eb9a5a tidy(mm): clean up ModelOnDisk caching 2025-10-13 10:30:06 +11:00
psychedelicious
c53c731371 tidy(mm): clean up model heuristic utils 2025-10-13 10:30:06 +11:00
psychedelicious
951635fbee feat(mm): wip port main models to new api 2025-10-13 10:30:06 +11:00
psychedelicious
044648fe61 tidy(mm): removed unused model merge class 2025-10-13 10:30:06 +11:00
psychedelicious
111782d6c9 docs(mm): add todos 2025-10-13 10:30:06 +11:00
psychedelicious
f5cbf60fc0 feat(mm): wip port of main models to new api 2025-10-13 10:30:06 +11:00
psychedelicious
395b7d8bbf feat(mm): wip port of main models to new api 2025-10-13 10:30:06 +11:00
psychedelicious
934b3f8b87 feat(mm): wip port of main models to new api 2025-10-13 10:30:06 +11:00
psychedelicious
9745c25b1b refactor(mm): add config validation utils, make it all consistent and clean 2025-10-13 10:30:06 +11:00
psychedelicious
925698a688 feat(mm): port cnet to new api 2025-10-13 10:30:06 +11:00
psychedelicious
96bbd8a26e fix(mm): t2i base determination 2025-10-13 10:30:06 +11:00
psychedelicious
eb1ed245fe tidy(ui): use Extract to get model config types 2025-10-13 10:30:06 +11:00
psychedelicious
a118700cc8 feat(mm): port flux "control lora" and t2i adapter to new api 2025-10-13 10:30:06 +11:00
psychedelicious
eaddd6f533 refactor(mm): continue iterating on config 2025-10-13 10:30:06 +11:00
psychedelicious
7ca0a0a0fd tidy(mm): skip optimistic override handling for now 2025-10-13 10:30:06 +11:00
psychedelicious
d185b85fb7 feat(mm): port ip adapter to new api 2025-10-13 10:30:06 +11:00
psychedelicious
a35a49f585 feat(mm): port flux redux to new api 2025-10-13 10:30:06 +11:00
psychedelicious
3b606b6d63 feat(mm): make match helpers more succint 2025-10-13 10:30:05 +11:00
psychedelicious
d89472d3b1 feat(mm): port SigLIPDiffusersConfig to new api 2025-10-13 10:30:05 +11:00
psychedelicious
036ab04376 feat(mm): port CLIPVisionDiffusersConfig to new api 2025-10-13 10:30:05 +11:00
psychedelicious
e1a54badc1 fix(mm): fall back to UnknownModelConfig correctly 2025-10-13 10:30:05 +11:00
psychedelicious
bbecc86d0f tidy(mm): clarify that model id utils are private 2025-10-13 10:30:05 +11:00
psychedelicious
d4823b6869 fix(mm): abstractmethod bork 2025-10-13 10:30:05 +11:00
psychedelicious
3488975b2b refactor(mm): add model config parsing utils 2025-10-13 10:30:05 +11:00
psychedelicious
fd47da6842 refactor(mm): remove unused methods in config.py 2025-10-13 10:30:05 +11:00
psychedelicious
8399de9c25 refactor(mm): simplify model classification process
Previously, we had a multi-phase strategy to identify models from their
files on disk:
1. Run each model config classes' `matches()` method on the files. It
checks if the model could possibly be an identified as the candidate
model type. This was intended to be a quick check. Break on the first
match.
2. If we have a match, run the config class's `parse()` method. It
derive some additional model config attrs from the model files. This was
intended to encapsulate heavier operations that may require loading the
model into memory.
3. Derive the common model config attrs, like name, description,
calculate the hash, etc. Some of these are also heavier operations.

This strategy has some issues:
- It is not clear how the pieces fit together. There is some
back-and-forth between different methods and the config base class. It
is hard to trace the flow of logic until you fully wrap your head around
the system and therefore difficult to add a model architecture to the
probe.
- The assumption that we could do quick, lightweight checks before
heavier checks is incorrect. We often _must_ load the model state dict
in the `matches()` method. So there is no practical perf benefit to
splitting up the responsibility of `matches()` and `parse()`.
- Sometimes we need to do the same checks in `matches()` and `parse()`.
In these cases, splitting the logic is has a negative perf impact
because we are doing the same work twice.
- As we introduce the concept of an "unknown" model config (i.e. a model
that we cannot identify, but still record in the db; see #8582), we will
_always_ run _all_ the checks for every model. Therefore we need not try
to defer heavier checks or resource-intensive ops like hashing. We are
going to do them anyways.
- There are situations where a model may match multiple configs. One
known case are SD pipeline models with merged LoRAs. In the old probe
API, we relied on the implicit order of checks to know that if a model
matched for pipeline _and_ LoRA, we prefer the pipeline match. But, in
the new API, we do not have this implicit ordering of checks. To resolve
this in a resilient way, we need to get all matches up front, then use
tie-breaker logic to figure out which should win (or add "differential
diagnosis" logic to the matchers).
- Field overrides weren't handled well by this strategy. They were only
applied at the very end, if a model matched successfully. This means we
cannot tell the system "Hey, this model is type X with base Y. Trust me
bro.". We cannot override the match logic. As we move towards letting
users correct mis-identified models (see #8582), this is a requirement.

We can simplify the process significantly and better support "unknown"
models.

Firstly, model config classes now have a single `from_model_on_disk()`
method that attempts to construct an instance of the class from the
model files. This replaces the `matches()` and `parse()` methods.

If we fail to create the config instance, a special exception is raised
that indicates why we think the files cannot be identified as the given
model config class.

Next, the flow for model identification is a bit simpler:
- Derive all the common fields up-front (name, desc, hash, etc).
- Merge in overrides.
- Call `from_model_on_disk()` for every config class, passing in the
fields. Overrides are handled in this method.
- Record the results for each config class and choose the best one.

The identification logic is a bit more verbose, with the special
exceptions and handling of overrides, but it is very clear what is
happening.

The one downside I can think of for this strategy is we do need to check
every model type, instead of stopping at the first match. It's a bit
less efficient. In practice, however, this isn't a hot code path, and
the improved clarity is worth far more than perf optimizations that the
end user will likely never notice.
2025-10-13 10:30:05 +11:00
psychedelicious
0fd58681a2 feat(mm): make config_path optional 2025-10-13 10:30:05 +11:00