Defuser 0.0.26__tar.gz → 0.0.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {defuser-0.0.26 → defuser-0.0.28}/Defuser.egg-info/PKG-INFO +3 -3
  2. {defuser-0.0.26 → defuser-0.0.28}/PKG-INFO +3 -3
  3. {defuser-0.0.26 → defuser-0.0.28}/README.md +2 -2
  4. {defuser-0.0.26 → defuser-0.0.28}/defuser/model_registry.py +24 -0
  5. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/moe_experts_interface.py +4 -0
  6. {defuser-0.0.26 → defuser-0.0.28}/pyproject.toml +1 -1
  7. {defuser-0.0.26 → defuser-0.0.28}/tests/test_candidate_coverage.py +19 -0
  8. {defuser-0.0.26 → defuser-0.0.28}/tests/test_meta_model_defusion.py +73 -1
  9. {defuser-0.0.26 → defuser-0.0.28}/Defuser.egg-info/SOURCES.txt +0 -0
  10. {defuser-0.0.26 → defuser-0.0.28}/Defuser.egg-info/dependency_links.txt +0 -0
  11. {defuser-0.0.26 → defuser-0.0.28}/Defuser.egg-info/requires.txt +0 -0
  12. {defuser-0.0.26 → defuser-0.0.28}/Defuser.egg-info/top_level.txt +0 -0
  13. {defuser-0.0.26 → defuser-0.0.28}/LICENSE +0 -0
  14. {defuser-0.0.26 → defuser-0.0.28}/defuser/__init__.py +0 -0
  15. {defuser-0.0.26 → defuser-0.0.28}/defuser/checkpoint_ops.py +0 -0
  16. {defuser-0.0.26 → defuser-0.0.28}/defuser/defuser.py +0 -0
  17. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/__init__.py +0 -0
  18. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/glm4v.py +0 -0
  19. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/model_patches.py +0 -0
  20. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/replace_modules.py +0 -0
  21. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/runtime_defusion.py +0 -0
  22. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/__init__.py +0 -0
  23. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/common.py +0 -0
  24. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/glm4_moe.py +0 -0
  25. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/glm4_moe_lite.py +0 -0
  26. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/mixtral.py +0 -0
  27. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/qwen2_moe.py +0 -0
  28. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/qwen3_moe.py +0 -0
  29. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/qwen3_next.py +0 -0
  30. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/unfused_moe/qwen3_omni_moe.py +0 -0
  31. {defuser-0.0.26 → defuser-0.0.28}/defuser/modeling/update_module.py +0 -0
  32. {defuser-0.0.26 → defuser-0.0.28}/defuser/utils/__init__.py +0 -0
  33. {defuser-0.0.26 → defuser-0.0.28}/defuser/utils/common.py +0 -0
  34. {defuser-0.0.26 → defuser-0.0.28}/defuser/utils/device.py +0 -0
  35. {defuser-0.0.26 → defuser-0.0.28}/defuser/utils/hf.py +0 -0
  36. {defuser-0.0.26 → defuser-0.0.28}/defuser/utils/model.py +0 -0
  37. {defuser-0.0.26 → defuser-0.0.28}/setup.cfg +0 -0
  38. {defuser-0.0.26 → defuser-0.0.28}/setup.py +0 -0
  39. {defuser-0.0.26 → defuser-0.0.28}/tests/test_convert_model.py +0 -0
  40. {defuser-0.0.26 → defuser-0.0.28}/tests/test_device_utils.py +0 -0
  41. {defuser-0.0.26 → defuser-0.0.28}/tests/test_filter_rules.py +0 -0
  42. {defuser-0.0.26 → defuser-0.0.28}/tests/test_moe_experts_interface.py +0 -0
  43. {defuser-0.0.26 → defuser-0.0.28}/tests/test_replace_modules_tracker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Defuser
3
- Version: 0.0.26
3
+ Version: 0.0.28
4
4
  Summary: Model defuser helper for HF Transformers.
5
5
  Author-email: ModelCloud <qubitium@modelcloud.ai>
6
6
  License-Expression: Apache-2.0
@@ -92,8 +92,8 @@ Defuser currently supports the following `transformers>=5.3.0` `model_type` valu
92
92
 
93
93
  | Pattern | Supported model types | Defused op performed ⚙️ |
94
94
  | --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
95
- | Standard routed expert tensors 🧱 | `deepseek_v2`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
96
- | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
95
+ | Standard routed expert tensors 🧱 | `deepseek_v2`, `diffusion_gemma`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
96
+ | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm5_next`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
97
97
  | Transposed or packed expert tensors | `gpt_oss`, `phimoe` | Splits transposed fused expert `gate_up_proj` tensors into per-expert `gate_proj` + `up_proj`, preserves expert bias when present, and converts expert tensors into numbered expert `nn.Linear` modules. |
98
98
  | Flattened expert layout | `dbrx` | Rebuilds the flattened DBRX expert FFN weights into numbered expert `gate_proj`, `up_proj`, and `down_proj` `nn.Linear` modules. |
99
99
  | Batched expert-input execution | `llama4` | Runtime expert tensor defusion plus preservation of the llama4 batched expert-input execution contract. |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Defuser
3
- Version: 0.0.26
3
+ Version: 0.0.28
4
4
  Summary: Model defuser helper for HF Transformers.
5
5
  Author-email: ModelCloud <qubitium@modelcloud.ai>
6
6
  License-Expression: Apache-2.0
@@ -92,8 +92,8 @@ Defuser currently supports the following `transformers>=5.3.0` `model_type` valu
92
92
 
93
93
  | Pattern | Supported model types | Defused op performed ⚙️ |
94
94
  | --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
95
- | Standard routed expert tensors 🧱 | `deepseek_v2`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
96
- | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
95
+ | Standard routed expert tensors 🧱 | `deepseek_v2`, `diffusion_gemma`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
96
+ | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm5_next`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
97
97
  | Transposed or packed expert tensors | `gpt_oss`, `phimoe` | Splits transposed fused expert `gate_up_proj` tensors into per-expert `gate_proj` + `up_proj`, preserves expert bias when present, and converts expert tensors into numbered expert `nn.Linear` modules. |
98
98
  | Flattened expert layout | `dbrx` | Rebuilds the flattened DBRX expert FFN weights into numbered expert `gate_proj`, `up_proj`, and `down_proj` `nn.Linear` modules. |
99
99
  | Batched expert-input execution | `llama4` | Runtime expert tensor defusion plus preservation of the llama4 batched expert-input execution contract. |
@@ -66,8 +66,8 @@ Defuser currently supports the following `transformers>=5.3.0` `model_type` valu
66
66
 
67
67
  | Pattern | Supported model types | Defused op performed ⚙️ |
68
68
  | --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
69
- | Standard routed expert tensors 🧱 | `deepseek_v2`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
70
- | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
69
+ | Standard routed expert tensors 🧱 | `deepseek_v2`, `diffusion_gemma`, `dots1`, `ernie4_5_moe`, `ernie4_5_vl_moe`, `exaone_moe`, `flex_olmo`, `glm4_moe_lite`, `glm4v_moe`, `hunyuan_v1_moe`, `jamba`, `laguna`, `lfm2_moe`, `minimax`, `minimax_m2`, `olmoe`, `qwen3_vl_moe`, `solar_open`, `solar_open2` | Splits fused expert tensors or registered expert buffers into numbered expert `nn.Linear` modules with per-expert `gate_proj`, `up_proj`, and `down_proj`. |
70
+ | Mixed sparse and shared experts | `deepseek_v3`, `deepseek_v32`, `deepseek_v4`, `glm5_next`, `glm_moe_dsa`, `qwen3_5_moe`, `qwen3_5_moe_text`, `qwen4_exp`, `qwen4_exp_text` | Runtime expert tensor defusion for routed experts while preserving the model's shared-expert path. |
71
71
  | Transposed or packed expert tensors | `gpt_oss`, `phimoe` | Splits transposed fused expert `gate_up_proj` tensors into per-expert `gate_proj` + `up_proj`, preserves expert bias when present, and converts expert tensors into numbered expert `nn.Linear` modules. |
72
72
  | Flattened expert layout | `dbrx` | Rebuilds the flattened DBRX expert FFN weights into numbered expert `gate_proj`, `up_proj`, and `down_proj` `nn.Linear` modules. |
73
73
  | Batched expert-input execution | `llama4` | Runtime expert tensor defusion plus preservation of the llama4 batched expert-input execution contract. |
@@ -46,6 +46,21 @@ MODEL_CONFIG = {
46
46
  "dia": {
47
47
  "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
48
48
  },
49
+ "diffusion_gemma": {
50
+ "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
51
+ PATCH.EXPERTS_DEFUSE: [
52
+ {
53
+ # DiffusionGemma's fused experts need an instance-level
54
+ # implementation after defusion so their per-expert Linear
55
+ # leaves remain compatible with the upstream routing call.
56
+ "module_class": (
57
+ "transformers.models.diffusion_gemma.modeling_diffusion_gemma."
58
+ "DiffusionGemmaTextExperts"
59
+ ),
60
+ "forward_impl": "linear_loop",
61
+ }
62
+ ],
63
+ },
49
64
  "dots1": {
50
65
  "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
51
66
  },
@@ -199,6 +214,15 @@ MODEL_CONFIG = {
199
214
  "glm_image": {
200
215
  "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
201
216
  },
217
+ "glm5_next": {
218
+ "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
219
+ PATCH.EXPERTS_DEFUSE: [
220
+ {
221
+ "module_class": "transformers.models.glm5_next.modeling_glm5_next.Glm5NextTextExperts",
222
+ "forward_impl": "linear_loop",
223
+ }
224
+ ],
225
+ },
202
226
  "glm_moe_dsa": {
203
227
  "min_transformers_version": MIN_SUPPORTED_TRANSFORMERS_VERSION,
204
228
  },
@@ -282,6 +282,10 @@ def _matching_experts_defuse_spec(module: nn.Module, specs: list[dict]) -> dict
282
282
 
283
283
  def _install_instance_forward(module: nn.Module, implementation: str) -> None:
284
284
  """Attach a generic forward implementation directly to one experts module."""
285
+ if implementation == LINEAR_LOOP_IMPL:
286
+ module.forward = MethodType(linear_loop_experts_forward, module)
287
+ return
288
+
285
289
  if implementation == BATCHED_INPUT_IMPL:
286
290
  module.forward = MethodType(batched_input_experts_forward, module)
287
291
  return
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
 
10
10
  [project]
11
11
  name = "Defuser"
12
- version = "0.0.26"
12
+ version = "0.0.28"
13
13
  description = "Model defuser helper for HF Transformers."
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.9"
@@ -177,6 +177,24 @@ STANDARD_MOE_CASES = [
177
177
  "route_indices": [[0], [1], [2], [3], [0]],
178
178
  "expert_attrs": ("gate_proj", "up_proj", "down_proj"),
179
179
  },
180
+ {
181
+ "model_type": "glm5_next",
182
+ "module_path": "transformers.models.glm5_next.modeling_glm5_next",
183
+ "class_name": "Glm5NextTextExperts",
184
+ "config_module": "transformers.models.glm5_next.configuration_glm5_next",
185
+ "config_name": "Glm5NextTextConfig",
186
+ "config_updates": {
187
+ "hidden_size": 64,
188
+ "moe_intermediate_size": 32,
189
+ "n_routed_experts": 4,
190
+ "hidden_act": "silu",
191
+ "swiglu_limit": 1.0,
192
+ "_experts_implementation": "grouped_mm",
193
+ },
194
+ "input_dim": 64,
195
+ "route_indices": [[0], [1], [2], [3], [0]],
196
+ "expert_attrs": ("gate_proj", "up_proj", "down_proj"),
197
+ },
180
198
  {
181
199
  "model_type": "dots1",
182
200
  "module_path": "transformers.models.dots1.modeling_dots1",
@@ -576,6 +594,7 @@ ALL_CANDIDATE_MODEL_TYPES = {
576
594
  "glm4_moe_lite",
577
595
  "glm4v",
578
596
  "glm4v_moe",
597
+ "glm5_next",
579
598
  "glm_image",
580
599
  "glm_moe_dsa",
581
600
  "glm_ocr",
@@ -138,7 +138,49 @@ def _mutate_common_config_tree(config, visited: set[int] | None = None) -> None:
138
138
 
139
139
  def _build_model_config(case: dict):
140
140
  """Construct a small config tree for one registered public model type."""
141
- config = _load(case["config_module"], case["config_class"])()
141
+ config_cls = _load(case["config_module"], case["config_class"])
142
+ if case["model_type"] == "diffusion_gemma":
143
+ # Unlike the generic cases, DiffusionGemma validates its nested text /
144
+ # vision configs during construction; provide a minimal valid pair so
145
+ # this registry test remains a meta-only structural check.
146
+ return config_cls(
147
+ text_config={
148
+ "vocab_size": 128,
149
+ "hidden_size": 64,
150
+ "intermediate_size": 128,
151
+ "moe_intermediate_size": 32,
152
+ "num_hidden_layers": 2,
153
+ "num_attention_heads": 4,
154
+ "num_key_value_heads": 1,
155
+ "num_global_key_value_heads": 1,
156
+ "head_dim": 16,
157
+ "global_head_dim": 16,
158
+ "num_experts": 4,
159
+ "top_k_experts": 1,
160
+ "max_position_embeddings": 64,
161
+ "sliding_window": 8,
162
+ "layer_types": ["sliding_attention", "full_attention"],
163
+ "use_bidirectional_attention": "vision",
164
+ },
165
+ vision_config={
166
+ "hidden_size": 64,
167
+ "intermediate_size": 128,
168
+ "num_hidden_layers": 1,
169
+ "num_attention_heads": 4,
170
+ "num_key_value_heads": 4,
171
+ "head_dim": 16,
172
+ "max_position_embeddings": 64,
173
+ "patch_size": 4,
174
+ "pooling_kernel_size": 1,
175
+ "position_embedding_size": 16,
176
+ },
177
+ canvas_length=4,
178
+ image_token_id=124,
179
+ boi_token_id=125,
180
+ eoi_token_id=126,
181
+ )
182
+
183
+ config = config_cls()
142
184
  _mutate_common_config_tree(config)
143
185
 
144
186
  model_type = case["model_type"]
@@ -166,6 +208,8 @@ def _build_model_config(case: dict):
166
208
  }
167
209
  elif model_type == "glm4_moe":
168
210
  config.first_k_dense_replace = -1
211
+ elif model_type == "glm5_next":
212
+ config.text_config.mlp_layer_types = ["sparse"] * config.text_config.num_hidden_layers
169
213
  elif model_type == "glm_moe_dsa":
170
214
  config.mlp_layer_types = ["sparse"] * config.num_hidden_layers
171
215
  elif model_type == "granitemoehybrid":
@@ -388,6 +432,21 @@ META_MODEL_CASES = [
388
432
  "target_class_paths": ("transformers.models.dots1.modeling_dots1.Dots1NaiveMoe",),
389
433
  "validator": "experts",
390
434
  },
435
+ {
436
+ "model_type": "diffusion_gemma",
437
+ "mode": "convert",
438
+ "model_module": "transformers.models.diffusion_gemma.modeling_diffusion_gemma",
439
+ "model_class": "DiffusionGemmaForBlockDiffusion",
440
+ "config_module": "transformers.models.diffusion_gemma.configuration_diffusion_gemma",
441
+ "config_class": "DiffusionGemmaConfig",
442
+ "target_class_paths": (
443
+ "transformers.models.diffusion_gemma.modeling_diffusion_gemma.DiffusionGemmaTextExperts",
444
+ ),
445
+ "validator": "experts",
446
+ # There are separate experts blocks in the encoder and decoder; seeing
447
+ # both ensures the declarative class-path patch is applied everywhere.
448
+ "min_targets": 2,
449
+ },
391
450
  {
392
451
  "model_type": "ernie4_5_moe",
393
452
  "mode": "convert",
@@ -500,6 +559,19 @@ META_MODEL_CASES = [
500
559
  "target_class_paths": ("transformers.models.glm_image.modeling_glm_image.GlmImageTextMLP",),
501
560
  "validator": "dense_split",
502
561
  },
562
+ {
563
+ "model_type": "glm5_next",
564
+ "mode": "convert",
565
+ "model_module": "transformers.models.glm5_next.modeling_glm5_next",
566
+ "model_class": "Glm5NextForConditionalGeneration",
567
+ "config_module": "transformers.models.glm5_next.configuration_glm5_next",
568
+ "config_class": "Glm5NextConfig",
569
+ "target_class_paths": (
570
+ "transformers.models.glm5_next.modeling_glm5_next.Glm5NextTextExperts",
571
+ ),
572
+ "validator": "experts",
573
+ "min_targets": 2,
574
+ },
503
575
  {
504
576
  "model_type": "glm_moe_dsa",
505
577
  "mode": "convert",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes