gabfssilva commited on
Commit
6c4bc5b
·
verified ·
1 Parent(s): 9fa4f83

Upload folder using huggingface_hub

Browse files
README.md ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ license_link: https://huggingface.co/tencent/Hy3/blob/main/LICENSE
4
+ base_model: tencent/Hy3
5
+ base_model_relation: quantized
6
+ library_name: mlx
7
+ pipeline_tag: text-generation
8
+ tags:
9
+ - mlx
10
+ - oq
11
+ - quantized
12
+ - moe
13
+ - hunyuan
14
+ ---
15
+ # Hy3 (MLX, oQ2)
16
+
17
+ Calibrated 2-bit MLX quantization of [tencent/Hy3](https://huggingface.co/tencent/Hy3) (Hunyuan 3.0, 295B-A21B MoE), produced with **omlx** oQ at level 2 — **~2.7 bits/weight effective**, 92 GB on disk. Data-driven mixed precision: bits are allocated per-tensor from a measured sensitivity map, not a fixed rule. For Apple Silicon.
18
+
19
+ ## Requirements
20
+
21
+ mlx-lm doesn't support the `hy_v3` architecture yet — there's an open PR: [mlx-lm#1211](https://github.com/ml-explore/mlx-lm/pull/1211). Until it lands, install mlx-lm from the PR branch, otherwise the model won't load:
22
+
23
+ ```bash
24
+ uv pip install "mlx-lm @ git+https://github.com/kernelpool/mlx-lm.git@add-hy3-preview"
25
+ ```
26
+
27
+ Once #1211 lands in a released mlx-lm, this should load as-is. If something breaks after that, open a discussion here asking for a re-upload.
28
+
29
+ ## How it was quantized
30
+
31
+ Hy3 is ~556 GB in BF16 — larger than RAM on a 128 GB machine — so oQ can't hold the full model to measure layer sensitivity, and omlx's automatic 4-bit sensitivity proxy trips the Metal command-buffer watchdog (`GPU Timeout`) on this hardware: the 4-bit proxy (~150 GB) overflows the default Metal working-set cap.
32
+
33
+ The path that worked, in two steps:
34
+
35
+ 1. **Intermediate `mixed_2_6`** — I first made a uniform heuristic mixed quant via `mlx_lm.convert` (2-bit base, 6-bit on a fixed structural set of layers). It's coherent but heavy (3.15 bpw, 108 GB, peaks ~116 GB — needs a raised Metal cap) and uneven on harder prompts.
36
+ 2. **oQ2 calibrated** — then I quantized to oQ2, passing the `mixed_2_6` as `sensitivity_model_path`, so oQ skips the failing auto-proxy, measures sensitivity on it (fits in memory, runs as inference — no watchdog), then streams the final quant tensor-by-tensor. It's **more resilient than `mixed_2_6` at less memory**.
37
+
38
+ ## Memory
39
+
40
+ Peak **~99 GB**, which fits under the **default** Metal working-set cap (107.5 GB on a 128 GB machine) — no `sysctl iogpu.wired_limit_mb` bump needed, unlike `mixed_2_6` (~116 GB peak). Headroom for the KV cache is tight at long context, so enabling oMLX's **TurboQuant KV is highly recommended** if possible — I got good performance with it at 3-bit.
41
+
42
+ ## Conversion check
43
+
44
+ Smoke-tested after conversion (`mlx_lm.generate`): coherent — solved `17 * 24 = 408` with correct step-by-step reasoning, no repetition loop (plain 2-bit and 2-bit+8-bit-router uniform quants both collapsed here; the calibrated oQ2 does not). On a **Macbook Pro M5 Max 128GB 40 GPU**: 33.6 tok/s generation, 5.05 tok/s prompt, peak 99 GB (short prompt).
45
+
46
+ ## Usage
47
+
48
+ ```bash
49
+ python -m mlx_lm generate --model mlx-community/Hy3-oQ2 --prompt "Explain Bayes' theorem in two sentences." --max-tokens 300
50
+ ```
51
+
52
+ ```python
53
+ from mlx_lm import load, generate
54
+ model, tokenizer = load("mlx-community/Hy3-oQ2")
55
+ ```
56
+
57
+ ## License
58
+
59
+ [Apache-2.0](https://huggingface.co/tencent/Hy3/blob/main/LICENSE), inherited from the base model. Refer to the original model card for architecture, benchmarks, and intended use.
chat_template.jinja ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {#- ----------‑‑‑ special token variables ‑‑‑---------- -#}
2
+ {%- set HYTK = ':opensource' %}
3
+ {%- set eos_token = '<|hy_eos{}|>'.format(HYTK) %}
4
+ {%- set bos_token = '<|hy_begin_of_sentence{}|>'.format(HYTK) %}
5
+ {%- set pad_token = '<|hy_pad{}|>'.format(HYTK) %}
6
+ {%- set user_token = '<|hy_User{}|>'.format(HYTK) %}
7
+ {%- set assistant_token = '<|hy_Assistant{}|>'.format(HYTK) %}
8
+ {%- set think_begin_token = '<think{}>'.format(HYTK) %}
9
+ {%- set think_end_token = '</think{}>'.format(HYTK) %}
10
+ {%- set toolcalls_begin_token = '<tool_calls{}>'.format(HYTK) %}
11
+ {%- set toolcalls_end_token = '</tool_calls{}>'.format(HYTK) %}
12
+ {%- set toolcall_begin_token = '<tool_call{}>'.format(HYTK) %}
13
+ {%- set toolcall_end_token = '</tool_call{}>'.format(HYTK) %}
14
+ {%- set toolsep_token = '<tool_sep{}>'.format(HYTK) %}
15
+ {%- set argkey_begin_token = '<arg_key{}>'.format(HYTK) %}
16
+ {%- set argkey_end_token = '</arg_key{}>'.format(HYTK) %}
17
+ {%- set argvalue_begin_token = '<arg_value{}>'.format(HYTK) %}
18
+ {%- set argvalue_end_token = '</arg_value{}>'.format(HYTK) %}
19
+ {%- set toolresponses_begin_token = '<tool_responses{}>'.format(HYTK) %}
20
+ {%- set toolresponses_end_token = '</tool_responses{}>'.format(HYTK) %}
21
+ {%- set toolresponse_begin_token = '<tool_response{}>'.format(HYTK) %}
22
+ {%- set toolresponse_end_token = '</tool_response{}>'.format(HYTK) %}
23
+ {%- set reasoning_mode_token = '<|reasoning_mode{}|>'.format(HYTK) %}
24
+
25
+ {#- ----------‑‑‑ hyperparameters variables ‑‑‑---------- -#}
26
+ {%- if not add_generation_prompt is defined %}
27
+ {%- set add_generation_prompt = false %}
28
+ {%- endif %}
29
+ {%- if not preserved_thinking is defined %}
30
+ {%- if not tools %}
31
+ {%- set preserved_thinking = false %}
32
+ {%- else %}
33
+ {%- set preserved_thinking = true %}
34
+ {%- endif %}
35
+ {%- endif %}
36
+ {%- if not is_training is defined %}
37
+ {%- set is_training = false %}
38
+ {%- endif %}
39
+
40
+ {%- if not reasoning_effort is defined %}
41
+ {%- set reasoning_effort = 'no_think' %}
42
+ {%- elif reasoning_effort not in ['high', 'low', 'no_think'] %}
43
+ {%- if reasoning_effort is none %}
44
+ {{- raise_exception('reasoning_effort error : None, should be no_think/low/high') }}
45
+ {%- else %}
46
+ {{- raise_exception('reasoning_effort error : ' + reasoning_effort + ', should be no_think/low/high') }}
47
+ {%- endif %}
48
+ {%- endif %}
49
+
50
+ {%- if fallback_strategy is defined and fallback_strategy == 'reasoning_toolcall_retry' %}
51
+ {%- set reasoning_effort = 'high' %}
52
+ {%- set add_generation_prompt = false %}
53
+ {%- endif %}
54
+ {%- if not raw_last_assistant is defined %}
55
+ {%- set raw_last_assistant = false %}
56
+ {%- endif %}
57
+
58
+ {%- macro visible_text(content) -%}
59
+ {%- if content is string -%}
60
+ {{- content }}
61
+ {%- elif content is iterable and content is not mapping -%}
62
+ {%- for item in content -%}
63
+ {%- if item is mapping and item.type == 'text' -%}
64
+ {{- item.text }}
65
+ {%- elif item is string -%}
66
+ {{- item }}
67
+ {%- endif -%}
68
+ {%- endfor -%}
69
+ {%- elif content is none -%}
70
+ {{- '' }}
71
+ {%- else -%}
72
+ {{- content }}
73
+ {%- endif -%}
74
+ {%- endmacro -%}
75
+
76
+ {%- set ns = namespace(last_user_index=-1) %}
77
+ {%- set sp_ns = namespace(system_prompt='', is_first_sp=true) %}
78
+ {%- for message in messages %}
79
+ {%- if message['role'] == 'system' %}
80
+ {%- set sp_ns.system_prompt = sp_ns.system_prompt + visible_text(message['content']) %}
81
+ {%- endif %}
82
+ {%- if message['role'] == 'user' %}
83
+ {%- set ns.last_user_index = loop.index0 %}
84
+ {%- endif %}
85
+ {%- endfor %}
86
+ {%- if reasoning_effort is defined and reasoning_effort is string and reasoning_effort != '' and not tools %}
87
+ {%- set sp_ns.system_prompt = sp_ns.system_prompt + reasoning_mode_token + 'reasoning_effort:' + reasoning_effort %}
88
+ {%- endif %}
89
+ {{- bos_token }}
90
+ {{- sp_ns.system_prompt }}
91
+ {%- if tools %}
92
+ {%- if sp_ns.system_prompt != '' %}
93
+ {{- '\n\n# Tools\n\nYou may call one or more functions to assist with the user query.' }}
94
+ {%- else %}
95
+ {{- '# Tools\n\nYou may call one or more functions to assist with the user query.' }}
96
+ {%- endif %}
97
+ {{- '\n\nYou are provided with function signatures within <tools></tools> XML tags:' }}
98
+ {{- '\n<tools>\n' }}
99
+ {%- for tool in tools %}
100
+ {%- if loop.index0 > 0 %}
101
+ {{- '\n' }}
102
+ {%- endif %}
103
+ {{- tool | tojson }}
104
+ {%- endfor %}
105
+ {{- '\n</tools>\n\n' }}
106
+ {{- 'For function call returns, you should first print ' + toolcalls_begin_token + '\n' }}
107
+ {{- 'For each function call, you should return object like:\n' }}
108
+ {{- toolcall_begin_token + '{function-name}' + toolsep_token + '\n' }}
109
+ {{- argkey_begin_token + '{arg-key-1}' + argkey_end_token + '\n' }}
110
+ {{- argvalue_begin_token + '{arg-value-1}' + argvalue_end_token + '\n' }}
111
+ {{- argkey_begin_token + '{arg-key-2}' + argkey_end_token + '\n' }}
112
+ {{- argvalue_begin_token + '{arg-value-2}' + argvalue_end_token + '\n' }}
113
+ {{- '...\n' }}
114
+ {{- toolcall_end_token + '\n' }}
115
+ {%- if reasoning_effort is defined and reasoning_effort is string and reasoning_effort != '' %}
116
+ {{- 'At the end of function call returns, you should print ' + toolcalls_end_token + reasoning_mode_token + 'reasoning_effort:' + reasoning_effort }}
117
+ {%- else %}
118
+ {{- 'At the end of function call returns, you should print ' + toolcalls_end_token }}
119
+ {%- endif %}
120
+ {%- endif %}
121
+
122
+ {%- set prev_ns = namespace(is_tool=false, is_tool_first=true) %}
123
+ {%- set last_ns = namespace(last_is_assistant=false) %}
124
+ {%- for message in messages %}
125
+ {%- if message['role'] == 'user' %}
126
+ {%- if prev_ns.is_tool %}
127
+ {{- toolresponses_end_token }}
128
+ {%- endif %}
129
+ {{- user_token + visible_text(message['content']) }}
130
+ {%- set prev_ns.is_tool = false %}
131
+ {%- endif %}
132
+ {%- if message['role'] == 'assistant' %}
133
+ {%- if is_training %}
134
+ {%- if 'reasoning_content' in message and message['reasoning_content'] is string %}
135
+ {%- set rc = message['reasoning_content'] %}
136
+ {%- elif 'reasoning' in message and message['reasoning'] is string %}
137
+ {%- set rc = message['reasoning'] %}
138
+ {%- else %}
139
+ {%- set rc = none %}
140
+ {%- endif %}
141
+ {%- if rc is not none %}
142
+ {%- set content = think_begin_token + rc + think_end_token + visible_text(message['content']) %}
143
+ {%- else %}
144
+ {%- set content = think_begin_token + think_end_token + visible_text(message['content']) %}
145
+ {%- endif %}
146
+ {%- else %}
147
+ {%- if ((preserved_thinking is defined and preserved_thinking) or loop.index0 > ns.last_user_index) %}
148
+ {%- if 'reasoning_content' in message and message['reasoning_content'] is string %}
149
+ {%- set rc = message['reasoning_content'] %}
150
+ {%- elif 'reasoning' in message and message['reasoning'] is string %}
151
+ {%- set rc = message['reasoning'] %}
152
+ {%- else %}
153
+ {%- set rc = none %}
154
+ {%- endif %}
155
+ {%- if rc is not none %}
156
+ {%- set content = think_begin_token + rc + think_end_token + visible_text(message['content']) %}
157
+ {%- else %}
158
+ {%- set content = think_begin_token + think_end_token + visible_text(message['content']) %}
159
+ {%- endif %}
160
+ {%- else %}
161
+ {%- set content = think_begin_token + think_end_token + visible_text(message['content']) %}
162
+ {%- endif %}
163
+ {%- endif %}
164
+ {%- if prev_ns.is_tool %}
165
+ {{- toolresponses_end_token }}
166
+ {%- endif %}
167
+ {{- assistant_token }}
168
+ {%- if message['tool_calls'] is defined and message['tool_calls'] %}
169
+ {%- set prev_ns.is_tool_first = true %}
170
+ {{- content }}
171
+ {{- toolcalls_begin_token + '\n' }}
172
+ {%- for tool in message['tool_calls'] %}
173
+ {%- set arguments = tool['function']['arguments'] %}
174
+ {{- toolcall_begin_token + tool['function']['name'] + toolsep_token + '\n' }}
175
+ {%- for key, value in arguments.items() %}
176
+ {{- argkey_begin_token + key + argkey_end_token + '\n' }}
177
+ {%- if value is not string %}
178
+ {%- set value = value | tojson(ensure_ascii=False) %}
179
+ {%- endif %}
180
+ {{- argvalue_begin_token + value + argvalue_end_token + '\n' }}
181
+ {%- endfor %}
182
+ {{- toolcall_end_token + '\n' }}
183
+ {%- endfor %}
184
+ {{- toolcalls_end_token + eos_token }}
185
+ {%- else %}
186
+ {%- if loop.last and raw_last_assistant %}
187
+ {{- visible_text(message['content']) }}
188
+ {%- elif not loop.last or is_training %}
189
+ {{- content + eos_token }}
190
+ {%- else %}
191
+ {{- content }}
192
+ {%- endif %}
193
+ {%- endif %}
194
+ {%- set prev_ns.is_tool = false %}
195
+ {%- endif %}
196
+ {%- if message['role'] == 'tool' %}
197
+ {%- set prev_ns.is_tool = true %}
198
+ {%- if prev_ns.is_tool_first %}
199
+ {{- toolresponses_begin_token + '\n' }}
200
+ {%- set prev_ns.is_tool_first = false %}
201
+ {%- endif %}
202
+ {{- toolresponse_begin_token + '\n' + visible_text(message['content']) + '\n' + toolresponse_end_token + '\n' }}
203
+ {%- endif %}
204
+ {%- if loop.last and message['role'] == 'assistant' %}
205
+ {%- set last_ns.last_is_assistant = true %}
206
+ {%- endif %}
207
+
208
+ {%- endfor %}
209
+ {%- if prev_ns.is_tool %}
210
+ {{- toolresponses_end_token }}
211
+ {%- endif %}
212
+ {%- if add_generation_prompt %}
213
+ {%- if not last_ns.last_is_assistant %}
214
+ {%- if reasoning_effort is defined and reasoning_effort in ['low', 'high'] %}
215
+ {{- assistant_token + think_begin_token }}
216
+ {%- elif reasoning_effort is defined and reasoning_effort == 'no_think' %}
217
+ {{- assistant_token + think_begin_token + think_end_token }}
218
+ {%- else %}
219
+ {{- assistant_token }}
220
+ {%- endif %}
221
+ {%- endif %}
222
+ {%- endif %}
config.json ADDED
The diff for this file is too large to render. See raw diff
 
generation_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 120000,
3
+ "do_sample": true,
4
+ "eos_token_id": 120025,
5
+ "pad_token_id": 120002,
6
+ "temperature": 0.9,
7
+ "top_k": -1,
8
+ "top_p": 1,
9
+ "transformers_version": "5.6.0"
10
+ }
model-00001-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0913eba317e5bb4fc86fe7b0ec476c97eecda925f14a0e21f4ef5b1d54f636fa
3
+ size 5032670254
model-00002-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c16eec2a71a175c0602cc27ecc35dba28fbff76fc1422769501c85e8367a8f21
3
+ size 5075244037
model-00003-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1c2eb2bd6b7fcb191d39c3a35dc6e887cd2b63ff6c5333ab3911b87604ff2286
3
+ size 5284832747
model-00004-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:54738bfcbfb94262115ad75bc58178f6637284762adce9d68d754c599ce19925
3
+ size 5284831871
model-00005-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6bc1064fd2c2752daf1b731096bf03ef4a6d9625372b0a270676cc92b1b2e6a6
3
+ size 5284832777
model-00006-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8f22756c753d934a10f57094458af56ee97278a97db165b3de3c6f237a84e2bc
3
+ size 5284832782
model-00007-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ed202dc2b79109de9f72bcfc0604e3d2936d98237ca0b08c557a467ed0abc16a
3
+ size 5284831901
model-00008-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0831436aa313054362a197af98b84a5fd97469ebf07622fffd92daa87f1a9cfe
3
+ size 5284832791
model-00009-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:91109bc07580d123b5845fd01af2188cf9a144721831ad0270b37be17296c418
3
+ size 5284832788
model-00010-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:84202cb36f53a92b4fcc22361702dc28de0802e834567b559ff5c0409871fc8b
3
+ size 5284831903
model-00011-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:588c4a9238fcf0f0d251349d0dd268aa0252af809ed0210b3aeb7dfaeaa94040
3
+ size 5284832779
model-00012-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:12dd8ff5e1c5fcdd917cb09bc95d8b4bcdf87bc73712950787ba76ce4bc2c5c8
3
+ size 5284832778
model-00013-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:21116cd87f32393d0f57465bacde1b38a5873fd0a185657b99a3410c98b5ce1e
3
+ size 5284831907
model-00014-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a042aee937be7afcd68b6cf864f71d08ab713a20735570d24314e6b6e11b9cf7
3
+ size 5284832793
model-00015-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eee95e53a7011c111c60bd92dd718b873b1e06633039b3e2f644b9148ddad93b
3
+ size 5284832780
model-00016-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b7f7bf98e6f31f8e2b739cb52458116174c40be3179416da61567a32b21cff42
3
+ size 5284831905
model-00017-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:573357c2717dd3831bc8bb3a4da253ae511ad382779bd9fa5a7697bd7a0b9052
3
+ size 5284832791
model-00018-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fe8f2cbe168c6cebaa9553a18ac1e075568a05a35c0c32aeb72e9ab414891267
3
+ size 5284832790
model-00019-of-00019.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:71207af9d1073db4261f876edd99f0944efb15d9f8668b507154ed8df42a5aa2
3
+ size 4152367808
model.safetensors.index.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
The diff for this file is too large to render. See raw diff