KyleHessling1 commited on
Commit
a51a849
·
verified ·
1 Parent(s): ba7e887

Add MLX 4-bit quantized weights + model card

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model:
4
+ - KyleHessling1/Qwopus-GLM-18B-Healed
5
+ - Jackrong/Qwopus3.5-9B-v3.5
6
+ - Jackrong/Qwen3.5-9B-GLM5.1-Distill-v1
7
+ tags:
8
+ - mlx
9
+ - mlx-4bit
10
+ - quantized
11
+ - apple-silicon
12
+ - merge
13
+ - frankenmerge
14
+ - qwen3.5
15
+ - reasoning
16
+ - text-generation
17
+ - conversational
18
+ - unsloth
19
+ - agent
20
+ - tool-use
21
+ - chain-of-thought
22
+ library_name: mlx
23
+ model_type: qwen3_5
24
+ pipeline_tag: text-generation
25
+ language:
26
+ - en
27
+ - zh
28
+ - ko
29
+ - ja
30
+ - fr
31
+ - de
32
+ - es
33
+ ---
34
+
35
+ # Qwopus-GLM-18B-Healed — MLX 4-bit
36
+
37
+ **Apple Silicon / MLX 4-bit quantization** of the healed Qwopus-GLM-18B frankenmerge. Ready to run on Macs with the [MLX](https://github.com/ml-explore/mlx) framework via [`mlx-lm`](https://github.com/ml-explore/mlx-lm).
38
+
39
+ - **Source (BF16):** [KyleHessling1/Qwopus-GLM-18B-Healed](https://huggingface.co/KyleHessling1/Qwopus-GLM-18B-Healed)
40
+ - **Q4_K_M GGUF (llama.cpp):** [KyleHessling1/Qwopus-GLM-18B-Merged-GGUF](https://huggingface.co/KyleHessling1/Qwopus-GLM-18B-Merged-GGUF)
41
+
42
+ ## Quickstart
43
+
44
+ ```bash
45
+ pip install -U "mlx-lm>=0.31.2"
46
+ ```
47
+
48
+ ```python
49
+ from mlx_lm import load, generate
50
+
51
+ model, tokenizer = load("KyleHessling1/Qwopus-GLM-18B-Healed-MLX-4bit")
52
+ print(generate(model, tokenizer, prompt="The capital of France is", max_tokens=64))
53
+ ```
54
+
55
+ Or from the CLI:
56
+
57
+ ```bash
58
+ python3 -m mlx_lm generate \
59
+ --model KyleHessling1/Qwopus-GLM-18B-Healed-MLX-4bit \
60
+ --prompt "Write a haiku about Apple Silicon." \
61
+ --max-tokens 128
62
+ ```
63
+
64
+ Runs comfortably on a 16–24 GB unified-memory Mac (M-series).
65
+
66
+ ## Quantization
67
+
68
+ | Property | Value |
69
+ |---|---|
70
+ | **Method** | MLX affine quantization (`mlx_lm.convert -q`) |
71
+ | **Bits / weight** | 4 (effective **4.502** after non-quantized layers) |
72
+ | **Group size** | 64 |
73
+ | **Non-quant dtype** | bfloat16 |
74
+ | **Output size** | **~8.4 GB** (2 safetensor shards) |
75
+ | **Quantizer version** | `mlx-lm` 0.31.2 / `mlx` 0.31.1 |
76
+
77
+ Reproducible from the BF16 source with:
78
+
79
+ ```bash
80
+ python3 -m mlx_lm convert \
81
+ --hf-path KyleHessling1/Qwopus-GLM-18B-Healed \
82
+ --mlx-path ./Qwopus-GLM-18B-Healed-MLX-4bit \
83
+ -q --q-bits 4 --q-group-size 64
84
+ ```
85
+
86
+ ## Base Model
87
+
88
+ A **64-layer frankenmerge** of two of [Jackrong's](https://huggingface.co/Jackrong) Qwen3.5-9B finetunes, healed with a 1000-step QLoRA fine-tune:
89
+
90
+ - **Layers 0–31:** [Jackrong/Qwopus3.5-9B-v3.5](https://huggingface.co/Jackrong/Qwopus3.5-9B-v3.5) (Opus reasoning distill)
91
+ - **Layers 32–63:** [Jackrong/Qwen3.5-9B-GLM5.1-Distill-v1](https://huggingface.co/Jackrong/Qwen3.5-9B-GLM5.1-Distill-v1) (GLM-5.1 reasoning distill)
92
+ - **Heal training:** 1000 steps QLoRA (rank 64) on Jackrong's training data to smooth the layer boundary
93
+
94
+ ### Architecture
95
+
96
+ | Property | Value |
97
+ |---|---|
98
+ | **Parameters** | ~18B |
99
+ | **Layers** | 64 (32 + 32) |
100
+ | **Hidden Size** | 4096 |
101
+ | **Attention Heads** | 16 (4 KV heads, GQA) |
102
+ | **Attention Type** | Hybrid (linear + full, every 4th layer) |
103
+ | **Context Length** | 262,144 tokens |
104
+ | **Source Precision** | BF16 |
105
+
106
+ ### Capability Suite (from base model)
107
+
108
+ Beats Qwen 3.6-35B-A3B MoE on a 44-test capability suite at less than half the VRAM:
109
+
110
+ | | Qwopus-GLM-18B (healed) | Qwen 3.6-35B MoE |
111
+ |---|---|---|
112
+ | **Score** | **40/44 (90.9%)** | 38/44 (86.4%) |
113
+ | **Tool Calling** | 6/6 | 6/6 |
114
+ | **Agentic** | 4/4 | 4/4 |
115
+ | **Programming** | 12/15 | 12/15 |
116
+
117
+ Frontend stress tests: **62/63 checks passed** across 6 complex HTML/CSS/JS generation tasks with perfectly balanced braces/parens and zero garbled output.
118
+
119
+ > Note: benchmarks were measured on the BF16 base / Q4_K_M GGUF. The MLX 4-bit weights are a separate quantization and have not been independently re-benchmarked — expect quality within normal 4-bit quantization variance.
120
+
121
+ ## Known Issues
122
+
123
+ - The tokenizer emits a Mistral-regex warning on load (inherited from the source repo). Benign for Qwen tokenization in practice.
124
+
125
+ ## Credits
126
+
127
+ All credit for the source models goes to **[Jackrong](https://huggingface.co/Jackrong)**. The heal training used his published datasets. See the [full merge documentation](https://huggingface.co/KyleHessling1/Qwopus-GLM-18B-Merged-GGUF/blob/main/MERGE_PROCESS.md) for the complete technical workflow.
128
+
129
+ MLX quantization by [@KyleHessling1](https://huggingface.co/KyleHessling1) using [mlx-lm](https://github.com/ml-explore/mlx-lm).
130
+
131
+ ## License
132
+
133
+ Apache 2.0 (inherited from source models)
134
+
135
+ ## Contact
136
+
137
+ Questions, issues, or cool projects? Reach out on X: [@KyleHessling1](https://x.com/KyleHessling1)
chat_template.jinja ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if tools %}
2
+ {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0].role == 'system' %}
4
+ {{- messages[0].content + '\n\n' }}
5
+ {%- endif %}
6
+ {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
7
+ {%- for tool in tools %}
8
+ {{- "\n" }}
9
+ {{- tool | tojson }}
10
+ {%- endfor %}
11
+ {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
12
+ {%- else %}
13
+ {%- if messages[0].role == 'system' %}
14
+ {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
15
+ {%- endif %}
16
+ {%- endif %}
17
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
+ {%- for message in messages[::-1] %}
19
+ {%- set index = (messages|length - 1) - loop.index0 %}
20
+ {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}
21
+ {%- set ns.multi_step_tool = false %}
22
+ {%- set ns.last_query_index = index %}
23
+ {%- endif %}
24
+ {%- endfor %}
25
+ {%- for message in messages %}
26
+ {%- if message.content is string %}
27
+ {%- set content = message.content %}
28
+ {%- else %}
29
+ {%- set content = '' %}
30
+ {%- endif %}
31
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
32
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
33
+ {%- elif message.role == "assistant" %}
34
+ {%- set reasoning_content = '' %}
35
+ {%- if message.reasoning_content is string %}
36
+ {%- set reasoning_content = message.reasoning_content %}
37
+ {%- else %}
38
+ {%- if '</think>' in content %}
39
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
40
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
41
+ {%- endif %}
42
+ {%- endif %}
43
+ {%- if loop.index0 > ns.last_query_index %}
44
+ {%- if loop.last or (not loop.last and reasoning_content) %}
45
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
46
+ {%- else %}
47
+ {{- '<|im_start|>' + message.role + '\n' + content }}
48
+ {%- endif %}
49
+ {%- else %}
50
+ {{- '<|im_start|>' + message.role + '\n' + content }}
51
+ {%- endif %}
52
+ {%- if message.tool_calls %}
53
+ {%- for tool_call in message.tool_calls %}
54
+ {%- if (loop.first and content) or (not loop.first) %}
55
+ {{- '\n' }}
56
+ {%- endif %}
57
+ {%- if tool_call.function %}
58
+ {%- set tool_call = tool_call.function %}
59
+ {%- endif %}
60
+ {{- '<tool_call>\n{"name": "' }}
61
+ {{- tool_call.name }}
62
+ {{- '", "arguments": ' }}
63
+ {%- if tool_call.arguments is string %}
64
+ {{- tool_call.arguments }}
65
+ {%- else %}
66
+ {{- tool_call.arguments | tojson }}
67
+ {%- endif %}
68
+ {{- '}\n</tool_call>' }}
69
+ {%- endfor %}
70
+ {%- endif %}
71
+ {{- '<|im_end|>\n' }}
72
+ {%- elif message.role == "tool" %}
73
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
74
+ {{- '<|im_start|>user' }}
75
+ {%- endif %}
76
+ {{- '\n<tool_response>\n' }}
77
+ {{- content }}
78
+ {{- '\n</tool_response>' }}
79
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
80
+ {{- '<|im_end|>\n' }}
81
+ {%- endif %}
82
+ {%- endif %}
83
+ {%- endfor %}
84
+ {%- if add_generation_prompt %}
85
+ {{- '<|im_start|>assistant
86
+ <think>
87
+ ' }}
88
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3_5ForConditionalGeneration"
4
+ ],
5
+ "eos_token_id": 248046,
6
+ "image_token_id": 248056,
7
+ "model_name": "/home/kylehessling/models/Qwopus-GLM-18B-merged",
8
+ "model_type": "qwen3_5",
9
+ "pad_token_id": 248055,
10
+ "quantization": {
11
+ "group_size": 64,
12
+ "bits": 4,
13
+ "mode": "affine"
14
+ },
15
+ "quantization_config": {
16
+ "group_size": 64,
17
+ "bits": 4,
18
+ "mode": "affine"
19
+ },
20
+ "text_config": {
21
+ "attention_bias": false,
22
+ "attention_dropout": 0.0,
23
+ "attn_output_gate": true,
24
+ "bos_token_id": null,
25
+ "torch_dtype": "bfloat16",
26
+ "eos_token_id": 248044,
27
+ "full_attention_interval": 4,
28
+ "head_dim": 256,
29
+ "hidden_act": "silu",
30
+ "hidden_size": 4096,
31
+ "initializer_range": 0.02,
32
+ "intermediate_size": 12288,
33
+ "layer_types": [
34
+ "linear_attention",
35
+ "linear_attention",
36
+ "linear_attention",
37
+ "full_attention",
38
+ "linear_attention",
39
+ "linear_attention",
40
+ "linear_attention",
41
+ "full_attention",
42
+ "linear_attention",
43
+ "linear_attention",
44
+ "linear_attention",
45
+ "full_attention",
46
+ "linear_attention",
47
+ "linear_attention",
48
+ "linear_attention",
49
+ "full_attention",
50
+ "linear_attention",
51
+ "linear_attention",
52
+ "linear_attention",
53
+ "full_attention",
54
+ "linear_attention",
55
+ "linear_attention",
56
+ "linear_attention",
57
+ "full_attention",
58
+ "linear_attention",
59
+ "linear_attention",
60
+ "linear_attention",
61
+ "full_attention",
62
+ "linear_attention",
63
+ "linear_attention",
64
+ "linear_attention",
65
+ "full_attention",
66
+ "linear_attention",
67
+ "linear_attention",
68
+ "linear_attention",
69
+ "full_attention",
70
+ "linear_attention",
71
+ "linear_attention",
72
+ "linear_attention",
73
+ "full_attention",
74
+ "linear_attention",
75
+ "linear_attention",
76
+ "linear_attention",
77
+ "full_attention",
78
+ "linear_attention",
79
+ "linear_attention",
80
+ "linear_attention",
81
+ "full_attention",
82
+ "linear_attention",
83
+ "linear_attention",
84
+ "linear_attention",
85
+ "full_attention",
86
+ "linear_attention",
87
+ "linear_attention",
88
+ "linear_attention",
89
+ "full_attention",
90
+ "linear_attention",
91
+ "linear_attention",
92
+ "linear_attention",
93
+ "full_attention",
94
+ "linear_attention",
95
+ "linear_attention",
96
+ "linear_attention",
97
+ "full_attention"
98
+ ],
99
+ "linear_conv_kernel_dim": 4,
100
+ "linear_key_head_dim": 128,
101
+ "linear_num_key_heads": 16,
102
+ "linear_num_value_heads": 32,
103
+ "linear_value_head_dim": 128,
104
+ "mamba_ssm_dtype": "float32",
105
+ "max_position_embeddings": 262144,
106
+ "mlp_only_layers": [],
107
+ "model_type": "qwen3_5_text",
108
+ "mtp_num_hidden_layers": 1,
109
+ "mtp_use_dedicated_embeddings": false,
110
+ "num_attention_heads": 16,
111
+ "num_hidden_layers": 64,
112
+ "num_key_value_heads": 4,
113
+ "pad_token_id": null,
114
+ "partial_rotary_factor": 0.25,
115
+ "rms_norm_eps": 1e-06,
116
+ "rope_parameters": {
117
+ "mrope_interleaved": true,
118
+ "mrope_section": [
119
+ 11,
120
+ 11,
121
+ 10
122
+ ],
123
+ "partial_rotary_factor": 0.25,
124
+ "rope_theta": 10000000,
125
+ "type": "default"
126
+ },
127
+ "tie_word_embeddings": false,
128
+ "use_cache": true,
129
+ "vocab_size": 248320
130
+ },
131
+ "tie_word_embeddings": false,
132
+ "torch_dtype": "bfloat16",
133
+ "unsloth_fixed": true,
134
+ "unsloth_version": "2026.4.6",
135
+ "use_cache": false,
136
+ "video_token_id": 248057,
137
+ "vision_end_token_id": 248054,
138
+ "vision_start_token_id": 248053
139
+ }
model-00001-of-00002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e1958be7d29393269f7bd108590995d0242cc7fc7465907543d7beda5ce55da8
3
+ size 5354562558
model-00002-of-00002.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5015fba0ed2bb901d3697d5a8b6923660b8eedaede6876cbd9d6f1c4b7faa7bd
3
+ size 3577494967
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:87a7830d63fcf43bf241c3c5242e96e62dd3fdc29224ca26fed8ea333db72de4
3
+ size 19989343
tokenizer_config.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "audio_bos_token": "<|audio_start|>",
4
+ "audio_eos_token": "<|audio_end|>",
5
+ "audio_token": "<|audio_pad|>",
6
+ "backend": "tokenizers",
7
+ "bos_token": null,
8
+ "clean_up_tokenization_spaces": false,
9
+ "eos_token": "<|im_end|>",
10
+ "errors": "replace",
11
+ "image_token": "<|image_pad|>",
12
+ "is_local": true,
13
+ "max_length": 4096,
14
+ "model_max_length": 262144,
15
+ "model_specific_special_tokens": {
16
+ "audio_bos_token": "<|audio_start|>",
17
+ "audio_eos_token": "<|audio_end|>",
18
+ "audio_token": "<|audio_pad|>",
19
+ "image_token": "<|image_pad|>",
20
+ "video_token": "<|video_pad|>",
21
+ "vision_bos_token": "<|vision_start|>",
22
+ "vision_eos_token": "<|vision_end|>"
23
+ },
24
+ "pad_token": "<|vision_pad|>",
25
+ "padding_side": "left",
26
+ "pretokenize_regex": "(?i:'s|'t|'re|'ve|'m|'ll|'d)|[^\\r\\n\\p{L}\\p{N}]?[\\p{L}\\p{M}]+|\\p{N}| ?[^\\s\\p{L}\\p{M}\\p{N}]+[\\r\\n]*|\\s*[\\r\\n]+|\\s+(?!\\S)|\\s+",
27
+ "processor_class": "Qwen3VLProcessor",
28
+ "split_special_tokens": false,
29
+ "stride": 0,
30
+ "tokenizer_class": "TokenizersBackend",
31
+ "tool_parser_type": "json_tools",
32
+ "truncation_side": "right",
33
+ "truncation_strategy": "longest_first",
34
+ "unk_token": null,
35
+ "video_token": "<|video_pad|>",
36
+ "vision_bos_token": "<|vision_start|>",
37
+ "vision_eos_token": "<|vision_end|>"
38
+ }