Skip to content

Commit 3273280

Browse files
FeepingCreatureForge AI (github.com/FeepingCreature/forge)
authored andcommitted
Add Anima architecture support
- resources.py: Add Arch.anima enum member with text_encoders (qwen_3_06b), supports_attention_guidance, search paths for TE/VAE, required resource IDs - workflow.py: Load separate CLIP (omnigen2 type) and VAE for anima in load_checkpoint_with_lora() - comfy_client.py: Add qwen_3_06b to text encoder model discovery Co-authored-by: Forge AI (github.com/FeepingCreature/forge) <noreply@forge-ai.invalid>
1 parent 0a52c1e commit 3273280

4 files changed

Lines changed: 22 additions & 3 deletions

File tree

ai_diffusion/comfy_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ def _find_text_encoder_models(model_list: Sequence[str]):
751751
kind = ResourceKind.text_encoder
752752
return {
753753
resource_id(kind, Arch.all, te): _find_model(model_list, kind, Arch.all, te)
754-
for te in ["clip_l", "clip_g", "t5", "qwen", "qwen_3_4b", "qwen_3_8b"]
754+
for te in ["clip_l", "clip_g", "t5", "qwen", "qwen_3_06b", "qwen_3_4b", "qwen_3_8b"]
755755
}
756756

757757

ai_diffusion/resources.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Arch(Enum):
9595
qwen_e = "Qwen Edit"
9696
qwen_e_p = "Qwen Edit Plus"
9797
qwen_l = "Qwen Layered"
98+
anima = "Anima"
9899
zimage = "Z-Image"
99100

100101
auto = "Automatic"
@@ -134,6 +135,8 @@ def from_string(string: str, model_type: str = "eps", filename: str | None = Non
134135
return Arch.qwen_l
135136
if string == "qwen-image":
136137
return Arch.qwen
138+
if string == "anima" or (string == "unknown" and "anima" in filename):
139+
return Arch.anima
137140
if string in {"z-image", "zimage"}:
138141
return Arch.zimage
139142
return None
@@ -187,7 +190,7 @@ def supports_clip_skip(self):
187190

188191
@property
189192
def supports_attention_guidance(self):
190-
return self in [Arch.sd15, Arch.sdxl, Arch.illu, Arch.illu_v]
193+
return self in [Arch.sd15, Arch.sdxl, Arch.illu, Arch.illu_v, Arch.anima]
191194

192195
@property
193196
def supports_cfg(self):
@@ -237,6 +240,8 @@ def text_encoders(self):
237240
return ["t5"]
238241
case Arch.qwen | Arch.qwen_e | Arch.qwen_e_p | Arch.qwen_l:
239242
return ["qwen"]
243+
case Arch.anima:
244+
return ["qwen_3_06b"]
240245
case Arch.zimage:
241246
return ["qwen_3_4b"]
242247
raise ValueError(f"Unsupported architecture: {self}")
@@ -258,6 +263,7 @@ def list():
258263
Arch.qwen_e,
259264
Arch.qwen_e_p,
260265
Arch.qwen_l,
266+
Arch.anima,
261267
Arch.zimage,
262268
]
263269

@@ -791,6 +797,7 @@ def is_required(kind: ResourceKind, arch: Arch, identifier: ControlMode | Upscal
791797
resource_id(ResourceKind.text_encoder, Arch.all, "qwen"): ["qwen_2.5_vl_7b", "qwen2.5-vl-7b", "qwen_2", "qwen-2", "qwen"],
792798
resource_id(ResourceKind.text_encoder, Arch.all, "qwen_3_4b"): ["qwen_3_4b", "qwen3-4b", "qwen3_4b", "qwen_3", "qwen-3"],
793799
resource_id(ResourceKind.text_encoder, Arch.all, "qwen_3_8b"): ["qwen_3_8b", "qwen3-8b", "qwen3_8b"],
800+
resource_id(ResourceKind.text_encoder, Arch.all, "qwen_3_06b"): ["qwen_3_06b"],
794801
resource_id(ResourceKind.vae, Arch.sd15, "default"): ["vae-ft-mse-840000-ema"],
795802
resource_id(ResourceKind.vae, Arch.sdxl, "default"): ["sdxl_vae"],
796803
resource_id(ResourceKind.vae, Arch.illu, "default"): ["sdxl_vae"],
@@ -805,6 +812,7 @@ def is_required(kind: ResourceKind, arch: Arch, identifier: ControlMode | Upscal
805812
resource_id(ResourceKind.vae, Arch.qwen_e, "default"): ["qwen"],
806813
resource_id(ResourceKind.vae, Arch.qwen_e_p, "default"): ["qwen"],
807814
resource_id(ResourceKind.vae, Arch.qwen_l, "default"): ["qwen_image_layered_vae"],
815+
resource_id(ResourceKind.vae, Arch.anima, "default"): ["qwen_image"],
808816
resource_id(ResourceKind.vae, Arch.zimage, "default"): ["z-image", "flux-", "flux_", "flux/", "flux1", "ae.s"],
809817
}
810818
# fmt: on
@@ -815,6 +823,7 @@ def is_required(kind: ResourceKind, arch: Arch, identifier: ControlMode | Upscal
815823
ResourceId(ResourceKind.text_encoder, Arch.qwen, "qwen"),
816824
ResourceId(ResourceKind.text_encoder, Arch.qwen_e, "qwen"),
817825
ResourceId(ResourceKind.text_encoder, Arch.qwen_e_p, "qwen"),
826+
ResourceId(ResourceKind.text_encoder, Arch.anima, "qwen_3_06b"),
818827
ResourceId(ResourceKind.text_encoder, Arch.zimage, "qwen_3_4b"),
819828
ResourceId(ResourceKind.text_encoder, Arch.flux2_4b, "qwen_3_4b"),
820829
ResourceId(ResourceKind.text_encoder, Arch.flux2_9b, "qwen_3_8b"),
@@ -834,6 +843,7 @@ def is_required(kind: ResourceKind, arch: Arch, identifier: ControlMode | Upscal
834843
ResourceId(ResourceKind.vae, Arch.qwen, "default"),
835844
ResourceId(ResourceKind.vae, Arch.qwen_e, "default"),
836845
ResourceId(ResourceKind.vae, Arch.qwen_e_p, "default"),
846+
ResourceId(ResourceKind.vae, Arch.anima, "default"),
837847
ResourceId(ResourceKind.vae, Arch.zimage, "default"),
838848
ResourceId(ResourceKind.vae, Arch.flux2_4b, "default"),
839849
ResourceId(ResourceKind.vae, Arch.flux2_9b, "default"),

ai_diffusion/workflow.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ def load_checkpoint_with_lora(w: ComfyWorkflow, checkpoint: CheckpointInput, mod
163163
clip = w.t5_tokenizer_options(clip, min_padding=1, min_length=0)
164164
case Arch.qwen | Arch.qwen_e | Arch.qwen_e_p | Arch.qwen_l:
165165
clip = w.load_clip(te["qwen"], type="qwen_image")
166+
case Arch.anima:
167+
clip = w.load_clip(te["qwen_3_06b"], type="omnigen2")
166168
case Arch.zimage:
167169
clip = w.load_clip(te["qwen_3_4b"], type="lumina2")
168170
case _:

tests/test_resources.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ def test_same_name_same_model():
4747
def test_resource_ids_exist():
4848
ids = chain(res.required_resource_ids, res.recommended_resource_ids)
4949
for resource_id in ids:
50-
if resource_id.arch in (Arch.sd3, Arch.qwen, Arch.qwen_e, Arch.qwen_e_p, Arch.flux2_9b):
50+
if resource_id.arch in (
51+
Arch.sd3,
52+
Arch.qwen,
53+
Arch.qwen_e,
54+
Arch.qwen_e_p,
55+
Arch.flux2_9b,
56+
Arch.anima,
57+
):
5158
continue # no model downloads yet
5259
model = res.find_resource(resource_id)
5360
assert model is not None, f"Resource ID {resource_id} not found"

0 commit comments

Comments
 (0)