Text Generation
MLX
Safetensors
qwen4_exp
omlx
oq
quantized
apple-silicon
mixture-of-experts
4-bit precision
long-context
conversational
tool-calling
speculative-decoding
mtp
Instructions to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with MLX:
# Make sure mlx-lm is installed # pip install --upgrade mlx-lm # Generate text with mlx-lm from mlx_lm import load, generate model, tokenizer = load("jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k") prompt = "Write a story about Einstein" messages = [{"role": "user", "content": prompt}] prompt = tokenizer.apply_chat_template( messages, add_generation_prompt=True ) text = generate(model, tokenizer, prompt=prompt, verbose=True) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Pi
How to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with Pi:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k"
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "mlx-lm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k" } ] } } }Run Pi
# Start Pi in your project directory: pi
- MLX LM
How to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Interactive chat REPL mlx_lm.chat --model "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k"
Run an OpenAI-compatible server
# Install MLX LM uv tool install mlx-lm # Start the server mlx_lm.server --model "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k" # Calling the OpenAI-compatible server with curl curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k", "messages": [ {"role": "user", "content": "Hello"} ] }' - Hermes Agent
How to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with Hermes Agent:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k"
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k with OpenClaw:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k"
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k" \ --custom-provider-id mlx-lm \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Add model card, configuration, and oMLX support
Browse files- .gitattributes +1 -0
- LICENSE +16 -0
- README.md +157 -0
- chat_template.jinja +170 -0
- config.json +0 -0
- generation_config.json +12 -0
- merges.txt +0 -0
- model.safetensors.index.json +0 -0
- omlx_support/LICENSE +190 -0
- omlx_support/model_settings.json +40 -0
- omlx_support/qwen4_cache_integration.py +381 -0
- omlx_support/qwen4_exp.py +1361 -0
- omlx_support/qwen4_mtp_integration.py +18 -0
- omlx_support/serve +33 -0
- omlx_support/sitecustomize.py +15 -0
- omlx_support/with-omlx-python +22 -0
- oq_imatrix_report.json +870 -0
- tokenizer.json +3 -0
- tokenizer_config.json +305 -0
- vocab.json +0 -0
.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
|
LICENSE
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Qwen Community License 1.0
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Qwen
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software, including the model weights, parameters, configuration files, inference code and associated documentation files (collectively, the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, sell, deploy, host, fine-tune, and create derivative works from (collectively, "Use" or "Using") copies of the Software; and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
| 6 |
+
|
| 7 |
+
1. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. If the Software (or any derivative works thereof) is Used for any of the licensee's commercial products or services that have more than 100,000,000 monthly active users or US$ 20,000,000 (or equivalent in other currencies) monthly revenue, respective model name must be prominently displayed on the user interface of such product or service; and,
|
| 8 |
+
|
| 9 |
+
2. If the licensee or any of its affiliates conducts a Model as a Service or AI Work Assistant business, the licensee shall obtain a separate license from Qwen before Using the Software or its derivative works for any commercial purpose. The foregoing requirement shall not apply to the licensee's internal Use of the Software, provided that such Use does not make the Software, its outputs, or its underlying model capabilities available to any third party.
|
| 10 |
+
|
| 11 |
+
"Model as a Service" means giving a third party access to language model inference or fine-tuning (e.g., via API or a hosted endpoint) in a manner that allows such third parties to exercise meaningful control over the inputs, parameters, or training data. This does not include the mere relaying of requests to models hosted by other third parties.
|
| 12 |
+
“AI Work Assistant” means an independent AI-powered product primarily designed for AI-assisted coding or office productivity (e.g., Qoder and QwenWork). It does not include: (a) a single-purpose AI tool (such as an AI translation tool); (b) an AI assistant primarily designed for a domain other than coding or office productivity (such as Taobao AI Shopping Assistant or AMap AI Chat); or (c) an AI assistant that is a feature of a product whose primary purpose is not AI-assisted coding or office productivity.
|
| 13 |
+
|
| 14 |
+
THE SOFTWARE AND ANY OUTPUT AND RESULTS THEREFROM ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL QWEN, ITS AFFILIATES OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. THE USE OF THE SOFTWARE MUST COMPLY WITH APPLICABLE LAWS AND REGULATIONS, AND MUST NOT INFRINGE THE INTELLECTUAL PROPERTY RIGHTS OF ANY THIRD PARTY.
|
| 15 |
+
|
| 16 |
+
For any questions regarding this license, please contact model-business@notice.qwencloud.com.
|
README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
base_model:
|
| 3 |
+
- Qwen/Qwen3.8-Flash-Next-FP8
|
| 4 |
+
base_model_relation: quantized
|
| 5 |
+
library_name: mlx
|
| 6 |
+
license: other
|
| 7 |
+
license_name: qwen-community-1.0
|
| 8 |
+
license_link: LICENSE
|
| 9 |
+
pipeline_tag: text-generation
|
| 10 |
+
tags:
|
| 11 |
+
- mlx
|
| 12 |
+
- safetensors
|
| 13 |
+
- qwen4_exp
|
| 14 |
+
- omlx
|
| 15 |
+
- oq
|
| 16 |
+
- quantized
|
| 17 |
+
- apple-silicon
|
| 18 |
+
- mixture-of-experts
|
| 19 |
+
- 4-bit
|
| 20 |
+
- long-context
|
| 21 |
+
- conversational
|
| 22 |
+
- tool-calling
|
| 23 |
+
- speculative-decoding
|
| 24 |
+
- mtp
|
| 25 |
+
---
|
| 26 |
+
|
| 27 |
+
# Qwen3.8 Flash Next oQ4e MTP 128K for oMLX
|
| 28 |
+
|
| 29 |
+
This is a community, text-only dynamic quantization of [Qwen/Qwen3.8-Flash-Next-FP8](https://huggingface.co/Qwen/Qwen3.8-Flash-Next-FP8) for Apple Silicon and oMLX.
|
| 30 |
+
|
| 31 |
+
It is designed for a 131,072-token context window on a Mac with 128 GiB of unified memory. The conversion removes the vision encoder and retains the released one-layer Multi-Token Prediction head for depth-1 speculative decoding. It is not an official Qwen release.
|
| 32 |
+
|
| 33 |
+
## Quantization
|
| 34 |
+
|
| 35 |
+
The model uses oMLX enhanced importance-matrix quantization with 4-bit affine, group-size 128 weights as the default. Precision is assigned by tensor family:
|
| 36 |
+
|
| 37 |
+
- The token embedding and language-model head use 4-bit affine quantization.
|
| 38 |
+
- Large linear and routed-expert weights use importance-matrix-guided mixed precision.
|
| 39 |
+
- Sensitive attention and shared-expert matrices retain higher precision, including 8-bit floors.
|
| 40 |
+
- Routers, recurrent state, convolutions, normalization, residual controls, and related control tensors retain BF16.
|
| 41 |
+
- The MTP head's 512 routed experts use importance-weighted 4-bit affine quantization at group size 128. Their three projections are stacked, avoiding 3,072 separate expert weight and scale arrays.
|
| 42 |
+
- MTP attention, shared-expert, and layer mixer matrices use 8-bit affine quantization. Fusion projections, the final mixer, routers, norms, gates, and injection controls retain BF16.
|
| 43 |
+
- The 51.2B-parameter PLE n-gram bank remains split into 128 shards. Shards 0 through 3 use 2-bit affine, group size 32. Shards 4 through 127 use 3-bit affine, group size 32.
|
| 44 |
+
|
| 45 |
+
The importance matrix was collected from 1,024 tool-heavy multilingual calibration samples at sequence length 512. The included `oq_imatrix_report.json` records the allocation inputs and coverage.
|
| 46 |
+
|
| 47 |
+
The MTP expert quantizer uses the calibrated activation importance of the analogous final backbone layer as a proxy. This preserves expert-specific weighting without claiming that the non-MTP calibration cache directly measured the draft head.
|
| 48 |
+
|
| 49 |
+
The resulting checkpoint contains 22 safetensors files and occupies 87.959 GiB. Its index contains 2,916 tensors, including 62 MTP tensors.
|
| 50 |
+
|
| 51 |
+
## Runtime requirements
|
| 52 |
+
|
| 53 |
+
This checkpoint is not compatible with stock Transformers, stock MLX-LM, or an oMLX release without Qwen4 experimental support. The exact text model, cache integration, and mixed-bit SSD-backed PLE implementation used for validation are included under `omlx_support`.
|
| 54 |
+
|
| 55 |
+
The tested software stack is:
|
| 56 |
+
|
| 57 |
+
- Apple Silicon
|
| 58 |
+
- MLX and mlx-metal 0.32.1
|
| 59 |
+
- The MLX-LM package bundled with oMLX 0.6.3rc3
|
| 60 |
+
- oMLX 0.6.3rc3
|
| 61 |
+
- Depth-1 MTP enabled through oMLX's generic native-MTP scheduler
|
| 62 |
+
|
| 63 |
+
The Qwen4 implementation is based on [oMLX pull request #3161](https://github.com/jundot/omlx/pull/3161) at commit `79e11cf86360ca800db5bdc45cec4ee582ada6b1`, with an adaptation for this checkpoint's per-shard 2-bit and 3-bit PLE metadata. The MTP equations follow draft [pull request #3163](https://github.com/jundot/omlx/pull/3163) at commit `b115fa5d928c11acf4588a55814a307d9161baff`, adapted to the sparse 128K text path and oMLX's installed generic speculative scheduler.
|
| 64 |
+
|
| 65 |
+
Install the tested MLX runtime inside the downloaded model directory, then launch the bundled oMLX wrapper:
|
| 66 |
+
|
| 67 |
+
```sh
|
| 68 |
+
hf download jedisct1/Qwen3.8-Flash-Next-oQ4e-MTP-128k \
|
| 69 |
+
--local-dir models/Qwen3.8-Flash-Next-oQ4e-MTP-128k
|
| 70 |
+
cd models/Qwen3.8-Flash-Next-oQ4e-MTP-128k
|
| 71 |
+
uv pip install --target .mlx-runtime mlx==0.32.1 mlx-metal==0.32.1
|
| 72 |
+
zsh omlx_support/serve
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
The launcher expects oMLX at `/Applications/oMLX.app`, listens only on `127.0.0.1:8766`, and uses `omlx` as its default local API key. Set `OMLX_APP_RESOURCES`, `OMLX_API_KEY`, `OMLX_PORT`, `OMLX_CACHE_DIR`, or `OMLX_MLX_RUNTIME` to override those paths and values.
|
| 76 |
+
|
| 77 |
+
It installs the included model settings into a fresh oMLX base path, permits one concurrent request, selects oMLX's balanced memory guard, disables the in-memory hot cache, memory-maps the PLE safetensors, and uses an SSD prompt cache. MTP is fixed at depth 1. Prompt priming is capped at 8,192 tokens so a long request cannot retain a second full-context attention timeline. The context budget is total input plus generated output, so keep that total at or below 131,072 tokens.
|
| 78 |
+
|
| 79 |
+
## Recommended generation settings
|
| 80 |
+
|
| 81 |
+
Thinking mode is enabled by default. The upstream recommended settings are included in `generation_config.json`:
|
| 82 |
+
|
| 83 |
+
```text
|
| 84 |
+
temperature: 1.0
|
| 85 |
+
top_p: 0.95
|
| 86 |
+
top_k: 20
|
| 87 |
+
min_p: 0.0
|
| 88 |
+
presence_penalty: 0.0
|
| 89 |
+
repetition_penalty: 1.0
|
| 90 |
+
```
|
| 91 |
+
|
| 92 |
+
For multi-turn agents, preserve `reasoning_content` between tool turns and keep `preserve_thinking` enabled.
|
| 93 |
+
|
| 94 |
+
## Validation
|
| 95 |
+
|
| 96 |
+
The artifact validator and strict lazy load found:
|
| 97 |
+
|
| 98 |
+
- 22 expected and readable safetensors files
|
| 99 |
+
- 2,916 indexed and stored tensors, including 62 MTP tensors
|
| 100 |
+
- No missing, unindexed, duplicated, or misplaced tensors
|
| 101 |
+
- No remaining per-expert MTP tensors after stacking
|
| 102 |
+
- All 128 PLE mixed-bit overrides applied as intended
|
| 103 |
+
- No missing or mismatched importance-matrix entries for measurable modules
|
| 104 |
+
|
| 105 |
+
On an M5 Max with 128 GiB of unified memory, the SSD-backed PLE implementation loaded 64.65 GB of Metal-backed model arrays. A fresh request containing 131,071 uncached prompt tokens generated one token, for exactly 131,072 total tokens, in 873.41 seconds with oMLX's balanced memory guard enabled. The guard reclaimed 4.86 GB and 5.87 GB of pooled Metal buffers during prefill instead of weakening Apple's 107.52 GiB working-set ceiling.
|
| 106 |
+
|
| 107 |
+
Live depth-1 requests activated the MTP path. The direct structured-call check accepted 39 of 45 draft tokens, or 86.7 percent. Across the six-turn Swival workflow, per-turn acceptance ranged from 72.5 to 87.7 percent. Acceptance is prompt-dependent and is not a quality guarantee.
|
| 108 |
+
|
| 109 |
+
## Tool calling
|
| 110 |
+
|
| 111 |
+
The original chat template and XML tool-call protocol are included. With MTP active, direct structured tool calls, continuation after a tool result, and a six-turn Swival file-write, checksum, read-back, and exact-byte comparison workflow were tested successfully. No identical tool invocation executed twice in that workflow.
|
| 112 |
+
|
| 113 |
+
Tool calling is stochastic and is not guaranteed to be flawless. Synthetic exact-call testing passed 17 of 18 cases with resident PLE and 16 of 18 cases with SSD-backed PLE. One failed response emitted duplicate calls. Agents should reject duplicate identical calls before execution, allow at most one bounded repair attempt, and fail closed if the repaired response remains invalid.
|
| 114 |
+
|
| 115 |
+
The dedicated MTP run passed 17 of 18 exact structured-call cases at the official thinking preset. The failed case emitted ordinary text claiming that it had called the requested tool but contained no structured call. The same case passed on an immediate isolated retry. MTP therefore matched the best prior non-MTP soak but did not eliminate the model's stochastic protocol failures.
|
| 116 |
+
|
| 117 |
+
The duplicate-call protection used during validation is implemented by Swival and is not part of these model weights.
|
| 118 |
+
|
| 119 |
+
## Limitations
|
| 120 |
+
|
| 121 |
+
- This is a text-only conversion. Image and video inputs are unsupported.
|
| 122 |
+
- MTP requires the bundled Qwen4 compatibility hook and oMLX's native-MTP scheduler. Stock MLX-LM cannot use this head.
|
| 123 |
+
- Prompt priming is intentionally disabled for prompts above 8,192 tokens. Long prompts still run correctly but begin drafting without a primed head history.
|
| 124 |
+
- The architecture supports 262,144 native tokens, but this conversion was validated and operationally limited to 131,072 total tokens.
|
| 125 |
+
- Only the stated Apple Silicon and oMLX configuration was tested.
|
| 126 |
+
- Quantization can reduce quality relative to the FP8 source.
|
| 127 |
+
- Greedy MTP-on and MTP-off checks produced the same final JSON answer but not a bit-identical hidden reasoning sequence. Multi-token target verification can take numerically different matrix paths.
|
| 128 |
+
- The model can produce incorrect content, malformed tool calls, duplicate tool calls, or unsafe actions. Tool execution requires independent validation and appropriate permission boundaries.
|
| 129 |
+
- The model inherits the limitations and intended-use considerations of the upstream Qwen model.
|
| 130 |
+
|
| 131 |
+
## Source and license
|
| 132 |
+
|
| 133 |
+
The conversion was produced from revision `bcd9f01ddc9cff2316eb84281bebcd5b058bddce` of [Qwen/Qwen3.8-Flash-Next-FP8](https://huggingface.co/Qwen/Qwen3.8-Flash-Next-FP8).
|
| 134 |
+
|
| 135 |
+
The weights remain subject to the Qwen Community License 1.0. Read `LICENSE` before using or redistributing the model, particularly its terms for commercial Model as a Service and AI Work Assistant businesses.
|
| 136 |
+
|
| 137 |
+
The bundled `omlx_support` code is distributed under the Apache License 2.0 in `omlx_support/LICENSE` and includes modifications to the implementations proposed in oMLX pull requests #3161 and #3163.
|
| 138 |
+
|
| 139 |
+
## Citation
|
| 140 |
+
|
| 141 |
+
```bibtex
|
| 142 |
+
@techreport{qwen2026design,
|
| 143 |
+
title = {On the Design of {Qwen3.8-Next} Architecture: Evaluation, Efficiency, and Training Stability},
|
| 144 |
+
author = {{Qwen Team}},
|
| 145 |
+
institution = {Alibaba Group},
|
| 146 |
+
month = {August},
|
| 147 |
+
year = {2026}
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
@misc{qwen3.8flashnext,
|
| 151 |
+
title = {{Qwen3.8-Flash-Next}: A New Architecture, Towards Ultimate Cost-Efficiency},
|
| 152 |
+
author = {{Qwen Team}},
|
| 153 |
+
month = {August},
|
| 154 |
+
year = {2026},
|
| 155 |
+
url = {https://qwen.ai/blog?id=qwen3.8-flash-next}
|
| 156 |
+
}
|
| 157 |
+
```
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- set image_count = namespace(value=0) %}
|
| 2 |
+
{%- set video_count = namespace(value=0) %}
|
| 3 |
+
{%- macro render_content(content, do_vision_count, is_system_content=false) %}
|
| 4 |
+
{%- if content is string %}
|
| 5 |
+
{{- content }}
|
| 6 |
+
{%- elif content is iterable and content is not mapping %}
|
| 7 |
+
{%- for item in content %}
|
| 8 |
+
{%- if 'image' in item or 'image_url' in item or item.type == 'image' %}
|
| 9 |
+
{%- if is_system_content %}
|
| 10 |
+
{{- raise_exception('System message cannot contain images.') }}
|
| 11 |
+
{%- endif %}
|
| 12 |
+
{%- if do_vision_count %}
|
| 13 |
+
{%- set image_count.value = image_count.value + 1 %}
|
| 14 |
+
{%- endif %}
|
| 15 |
+
{%- if add_vision_id %}
|
| 16 |
+
{{- 'Picture ' ~ image_count.value ~ ': ' }}
|
| 17 |
+
{%- endif %}
|
| 18 |
+
{{- '<|vision_start|><|image_pad|><|vision_end|>' }}
|
| 19 |
+
{%- elif 'video' in item or item.type == 'video' %}
|
| 20 |
+
{%- if is_system_content %}
|
| 21 |
+
{{- raise_exception('System message cannot contain videos.') }}
|
| 22 |
+
{%- endif %}
|
| 23 |
+
{%- if do_vision_count %}
|
| 24 |
+
{%- set video_count.value = video_count.value + 1 %}
|
| 25 |
+
{%- endif %}
|
| 26 |
+
{%- if add_vision_id %}
|
| 27 |
+
{{- 'Video ' ~ video_count.value ~ ': ' }}
|
| 28 |
+
{%- endif %}
|
| 29 |
+
{{- '<|vision_start|><|video_pad|><|vision_end|>' }}
|
| 30 |
+
{%- elif 'text' in item %}
|
| 31 |
+
{{- item.text }}
|
| 32 |
+
{%- else %}
|
| 33 |
+
{{- raise_exception('Unexpected item type in content.') }}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{%- endfor %}
|
| 36 |
+
{%- elif content is none or content is undefined %}
|
| 37 |
+
{{- '' }}
|
| 38 |
+
{%- else %}
|
| 39 |
+
{{- raise_exception('Unexpected content type.') }}
|
| 40 |
+
{%- endif %}
|
| 41 |
+
{%- endmacro %}
|
| 42 |
+
{%- if not messages %}
|
| 43 |
+
{{- raise_exception('No messages provided.') }}
|
| 44 |
+
{%- endif %}
|
| 45 |
+
{%- set reasoning_instructions = '' %}
|
| 46 |
+
{%- if enable_thinking is undefined or enable_thinking is true %}
|
| 47 |
+
{%- set resolved_reasoning_effort = reasoning_effort|default('xhigh') %}
|
| 48 |
+
{%- if resolved_reasoning_effort not in ('xhigh', 'medium', 'low') %}
|
| 49 |
+
{{- raise_exception('Unexpected reasoning effort ' ~ reasoning_effort ~ '. Supported types are xhigh (default), medium, and low.') }}
|
| 50 |
+
{%- endif %}
|
| 51 |
+
{%- if resolved_reasoning_effort == 'xhigh' %}
|
| 52 |
+
{%- set reasoning_instructions = 'Reasoning effort is set to xhigh. Please think carefully through the task, validate key assumptions, consider plausible alternatives, and prioritize correctness, consistency, and clarity in the final answer.' %}
|
| 53 |
+
{%- elif resolved_reasoning_effort == 'low' %}
|
| 54 |
+
{%- set reasoning_instructions = 'Reasoning effort is set to low. Keep your thinking brief and focused, moving directly to the conclusion without unnecessary elaboration.' %}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{%- endif %}
|
| 57 |
+
{%- if tools and tools is iterable and tools is not mapping %}
|
| 58 |
+
{{- '<|im_start|>system\n' }}
|
| 59 |
+
{%- if reasoning_instructions %}
|
| 60 |
+
{{- reasoning_instructions + '\n\n' }}
|
| 61 |
+
{%- endif %}
|
| 62 |
+
{{- "# Tools\n\nYou have access to the following functions:\n\n<tools>" }}
|
| 63 |
+
{%- for tool in tools %}
|
| 64 |
+
{{- "\n" }}
|
| 65 |
+
{{- tool | tojson }}
|
| 66 |
+
{%- endfor %}
|
| 67 |
+
{{- "\n</tools>" }}
|
| 68 |
+
{{- '\n\nIf you choose to call a function ONLY reply in the following format with NO suffix:\n\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>\nvalue_1\n</parameter>\n<parameter=example_parameter_2>\nThis is the value for the second parameter\nthat can span\nmultiple lines\n</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\nReminder:\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- Required parameters MUST be specified\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\n</IMPORTANT>' }}
|
| 69 |
+
{%- if messages[0].role == 'system' %}
|
| 70 |
+
{%- set content = render_content(messages[0].content, false, true)|trim %}
|
| 71 |
+
{%- if content %}
|
| 72 |
+
{{- '\n\n' + content }}
|
| 73 |
+
{%- endif %}
|
| 74 |
+
{%- endif %}
|
| 75 |
+
{{- '<|im_end|>\n' }}
|
| 76 |
+
{%- else %}
|
| 77 |
+
{%- if messages[0].role == 'system' %}
|
| 78 |
+
{%- set content = render_content(messages[0].content, false, true)|trim %}
|
| 79 |
+
{%- if content %}
|
| 80 |
+
{{- '<|im_start|>system\n' + (reasoning_instructions + '\n\n' if reasoning_instructions else '') + content + '<|im_end|>\n' }}
|
| 81 |
+
{%- elif reasoning_instructions %}
|
| 82 |
+
{{- '<|im_start|>system\n' + reasoning_instructions + '<|im_end|>\n' }}
|
| 83 |
+
{%- endif %}
|
| 84 |
+
{%- elif reasoning_instructions %}
|
| 85 |
+
{{- '<|im_start|>system\n' + reasoning_instructions + '<|im_end|>\n' }}
|
| 86 |
+
{%- endif %}
|
| 87 |
+
{%- endif %}
|
| 88 |
+
{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
|
| 89 |
+
{%- for message in messages[::-1] %}
|
| 90 |
+
{%- set index = (messages|length - 1) - loop.index0 %}
|
| 91 |
+
{%- if ns.multi_step_tool and message.role == "user" %}
|
| 92 |
+
{%- set content = render_content(message.content, false)|trim %}
|
| 93 |
+
{%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}
|
| 94 |
+
{%- set ns.multi_step_tool = false %}
|
| 95 |
+
{%- set ns.last_query_index = index %}
|
| 96 |
+
{%- endif %}
|
| 97 |
+
{%- endif %}
|
| 98 |
+
{%- endfor %}
|
| 99 |
+
{%- if ns.multi_step_tool %}
|
| 100 |
+
{{- raise_exception('No user query found in messages.') }}
|
| 101 |
+
{%- endif %}
|
| 102 |
+
{%- for message in messages %}
|
| 103 |
+
{%- set content = render_content(message.content, true)|trim %}
|
| 104 |
+
{%- if message.role == "system" %}
|
| 105 |
+
{%- if not loop.first %}
|
| 106 |
+
{{- raise_exception('System message must be at the beginning.') }}
|
| 107 |
+
{%- endif %}
|
| 108 |
+
{%- elif message.role == "user" %}
|
| 109 |
+
{{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
|
| 110 |
+
{%- elif message.role == "assistant" %}
|
| 111 |
+
{%- set reasoning_content = '' %}
|
| 112 |
+
{%- if message.reasoning_content is string %}
|
| 113 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 114 |
+
{%- endif %}
|
| 115 |
+
{%- set reasoning_content = reasoning_content|trim %}
|
| 116 |
+
{%- if preserve_thinking is undefined or preserve_thinking is true or loop.index0 > ns.last_query_index %}
|
| 117 |
+
{{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content + '\n</think>\n\n' + content }}
|
| 118 |
+
{%- else %}
|
| 119 |
+
{{- '<|im_start|>' + message.role + '\n' + content }}
|
| 120 |
+
{%- endif %}
|
| 121 |
+
{%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}
|
| 122 |
+
{%- for tool_call in message.tool_calls %}
|
| 123 |
+
{%- if tool_call.function is defined %}
|
| 124 |
+
{%- set tool_call = tool_call.function %}
|
| 125 |
+
{%- endif %}
|
| 126 |
+
{%- if loop.first %}
|
| 127 |
+
{%- if content|trim %}
|
| 128 |
+
{{- '\n\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
|
| 129 |
+
{%- else %}
|
| 130 |
+
{{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
|
| 131 |
+
{%- endif %}
|
| 132 |
+
{%- else %}
|
| 133 |
+
{{- '\n<tool_call>\n<function=' + tool_call.name + '>\n' }}
|
| 134 |
+
{%- endif %}
|
| 135 |
+
{%- if tool_call.arguments is defined and tool_call.arguments != '' %}
|
| 136 |
+
{%- for args_name, args_value in tool_call.arguments|items %}
|
| 137 |
+
{{- '<parameter=' + args_name + '>\n' }}
|
| 138 |
+
{%- set args_value = args_value | string if args_value is string else args_value | tojson | safe %}
|
| 139 |
+
{{- args_value }}
|
| 140 |
+
{{- '\n</parameter>\n' }}
|
| 141 |
+
{%- endfor %}
|
| 142 |
+
{%- endif %}
|
| 143 |
+
{{- '</function>\n</tool_call>' }}
|
| 144 |
+
{%- endfor %}
|
| 145 |
+
{%- endif %}
|
| 146 |
+
{{- '<|im_end|>\n' }}
|
| 147 |
+
{%- elif message.role == "tool" %}
|
| 148 |
+
{%- if loop.previtem and loop.previtem.role != "tool" %}
|
| 149 |
+
{{- '<|im_start|>user' }}
|
| 150 |
+
{%- endif %}
|
| 151 |
+
{{- '\n<tool_response>\n' }}
|
| 152 |
+
{{- content }}
|
| 153 |
+
{{- '\n</tool_response>' }}
|
| 154 |
+
{%- if not loop.last and loop.nextitem.role != "tool" %}
|
| 155 |
+
{{- '<|im_end|>\n' }}
|
| 156 |
+
{%- elif loop.last %}
|
| 157 |
+
{{- '<|im_end|>\n' }}
|
| 158 |
+
{%- endif %}
|
| 159 |
+
{%- else %}
|
| 160 |
+
{{- raise_exception('Unexpected message role.') }}
|
| 161 |
+
{%- endif %}
|
| 162 |
+
{%- endfor %}
|
| 163 |
+
{%- if add_generation_prompt %}
|
| 164 |
+
{{- '<|im_start|>assistant\n' }}
|
| 165 |
+
{%- if enable_thinking is defined and enable_thinking is false %}
|
| 166 |
+
{{- '<think>\n\n</think>\n\n' }}
|
| 167 |
+
{%- else %}
|
| 168 |
+
{{- '<think>\n' }}
|
| 169 |
+
{%- endif %}
|
| 170 |
+
{%- endif %}
|
config.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
generation_config.json
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 248044,
|
| 3 |
+
"do_sample": true,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
248046,
|
| 6 |
+
248044
|
| 7 |
+
],
|
| 8 |
+
"pad_token_id": 248044,
|
| 9 |
+
"temperature": 1.0,
|
| 10 |
+
"top_k": 20,
|
| 11 |
+
"top_p": 0.95
|
| 12 |
+
}
|
merges.txt
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
model.safetensors.index.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
omlx_support/LICENSE
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Apache License
|
| 2 |
+
Version 2.0, January 2004
|
| 3 |
+
http://www.apache.org/licenses/
|
| 4 |
+
|
| 5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 6 |
+
|
| 7 |
+
1. Definitions.
|
| 8 |
+
|
| 9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 11 |
+
|
| 12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 13 |
+
the copyright owner that is granting the License.
|
| 14 |
+
|
| 15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 16 |
+
other entities that control, are controlled by, or are under common
|
| 17 |
+
control with that entity. For the purposes of this definition,
|
| 18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 19 |
+
direction or management of such entity, whether by contract or
|
| 20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 22 |
+
|
| 23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 24 |
+
exercising permissions granted by this License.
|
| 25 |
+
|
| 26 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 27 |
+
including but not limited to software source code, documentation
|
| 28 |
+
source, and configuration files.
|
| 29 |
+
|
| 30 |
+
"Object" form shall mean any form resulting from mechanical
|
| 31 |
+
transformation or translation of a Source form, including but
|
| 32 |
+
not limited to compiled object code, generated documentation,
|
| 33 |
+
and conversions to other media types.
|
| 34 |
+
|
| 35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 36 |
+
Object form, made available under the License, as indicated by a
|
| 37 |
+
copyright notice that is included in or attached to the work
|
| 38 |
+
(an example is provided in the Appendix below).
|
| 39 |
+
|
| 40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 41 |
+
form, that is based on (or derived from) the Work and for which the
|
| 42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 44 |
+
of this License, Derivative Works shall not include works that remain
|
| 45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 46 |
+
the Work and Derivative Works thereof.
|
| 47 |
+
|
| 48 |
+
"Contribution" shall mean any work of authorship, including
|
| 49 |
+
the original version of the Work and any modifications or additions
|
| 50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 51 |
+
submitted to the Licensor for inclusion in the Work by the copyright owner
|
| 52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 54 |
+
means any form of electronic, verbal, or written communication sent
|
| 55 |
+
to the Licensor or its representatives, including but not limited to
|
| 56 |
+
communication on electronic mailing lists, source code control systems,
|
| 57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 59 |
+
excluding communication that is conspicuously marked or otherwise
|
| 60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 61 |
+
|
| 62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 63 |
+
on behalf of whom a Contribution has been received by the Licensor and
|
| 64 |
+
subsequently incorporated within the Work.
|
| 65 |
+
|
| 66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 71 |
+
Work and such Derivative Works in Source or Object form.
|
| 72 |
+
|
| 73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 76 |
+
(except as stated in this section) patent license to make, have made,
|
| 77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 78 |
+
where such license applies only to those patent claims licensable
|
| 79 |
+
by such Contributor that are necessarily infringed by their
|
| 80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 82 |
+
institute patent litigation against any entity (including a
|
| 83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 84 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 85 |
+
or contributory patent infringement, then any patent licenses
|
| 86 |
+
granted to You under this License for that Work shall terminate
|
| 87 |
+
as of the date such litigation is filed.
|
| 88 |
+
|
| 89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 90 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 91 |
+
modifications, and in Source or Object form, provided that You
|
| 92 |
+
meet the following conditions:
|
| 93 |
+
|
| 94 |
+
(a) You must give any other recipients of the Work or
|
| 95 |
+
Derivative Works a copy of this License; and
|
| 96 |
+
|
| 97 |
+
(b) You must cause any modified files to carry prominent notices
|
| 98 |
+
stating that You changed the files; and
|
| 99 |
+
|
| 100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 101 |
+
that You distribute, all copyright, patent, trademark, and
|
| 102 |
+
attribution notices from the Source form of the Work,
|
| 103 |
+
excluding those notices that do not pertain to any part of
|
| 104 |
+
the Derivative Works; and
|
| 105 |
+
|
| 106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 107 |
+
distribution, then any Derivative Works that You distribute must
|
| 108 |
+
include a readable copy of the attribution notices contained
|
| 109 |
+
within such NOTICE file, excluding any notices that do not
|
| 110 |
+
pertain to any part of the Derivative Works, in at least one
|
| 111 |
+
of the following places: within a NOTICE text file distributed
|
| 112 |
+
as part of the Derivative Works; within the Source form or
|
| 113 |
+
documentation, if provided along with the Derivative Works; or,
|
| 114 |
+
within a display generated by the Derivative Works, if and
|
| 115 |
+
wherever such third-party notices normally appear. The contents
|
| 116 |
+
of the NOTICE file are for informational purposes only and
|
| 117 |
+
do not modify the License. You may add Your own attribution
|
| 118 |
+
notices within Derivative Works that You distribute, alongside
|
| 119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 120 |
+
that such additional attribution notices cannot be construed
|
| 121 |
+
as modifying the License.
|
| 122 |
+
|
| 123 |
+
You may add Your own copyright statement to Your modifications and
|
| 124 |
+
may provide additional or different license terms and conditions
|
| 125 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 126 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 127 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 128 |
+
the conditions stated in this License.
|
| 129 |
+
|
| 130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 132 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 133 |
+
this License, without any additional terms or conditions.
|
| 134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 135 |
+
the terms of any separate license agreement you may have executed
|
| 136 |
+
with Licensor regarding such Contributions.
|
| 137 |
+
|
| 138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 140 |
+
except as required for reasonable and customary use in describing the
|
| 141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 142 |
+
|
| 143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 144 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 147 |
+
implied, including, without limitation, any warranties or conditions
|
| 148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 150 |
+
appropriateness of using or redistributing the Work and assume any
|
| 151 |
+
risks associated with Your exercise of permissions under this License.
|
| 152 |
+
|
| 153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 154 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 155 |
+
unless required by applicable law (such as deliberate and grossly
|
| 156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 157 |
+
liable to You for damages, including any direct, indirect, special,
|
| 158 |
+
incidental, or consequential damages of any character arising as a
|
| 159 |
+
result of this License or out of the use or inability to use the
|
| 160 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 161 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 162 |
+
other commercial damages or losses), even if such Contributor
|
| 163 |
+
has been advised of the possibility of such damages.
|
| 164 |
+
|
| 165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 168 |
+
or other liability obligations and/or rights consistent with this
|
| 169 |
+
License. However, in accepting such obligations, You may act only
|
| 170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 171 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 172 |
+
defend, and hold each Contributor harmless for any liability
|
| 173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 174 |
+
of your accepting any such warranty or additional liability.
|
| 175 |
+
|
| 176 |
+
END OF TERMS AND CONDITIONS
|
| 177 |
+
|
| 178 |
+
Copyright 2025 oMLX contributors
|
| 179 |
+
|
| 180 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 181 |
+
you may not use this file except in compliance with the License.
|
| 182 |
+
You may obtain a copy of the License at
|
| 183 |
+
|
| 184 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 185 |
+
|
| 186 |
+
Unless required by applicable law or agreed to in writing, software
|
| 187 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 188 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 189 |
+
See the License for the specific language governing permissions and
|
| 190 |
+
limitations under the License.
|
omlx_support/model_settings.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"version": 1,
|
| 3 |
+
"models": {
|
| 4 |
+
"Qwen3.8-Flash-Next-oQ4e-MTP-128k": {
|
| 5 |
+
"max_context_window": 131072,
|
| 6 |
+
"max_tokens": 32768,
|
| 7 |
+
"temperature": 1.0,
|
| 8 |
+
"top_p": 0.95,
|
| 9 |
+
"top_k": 20,
|
| 10 |
+
"min_p": 0.0,
|
| 11 |
+
"repetition_penalty": 1.0,
|
| 12 |
+
"presence_penalty": 0.0,
|
| 13 |
+
"force_sampling": true,
|
| 14 |
+
"chat_template_kwargs": {
|
| 15 |
+
"enable_thinking": true,
|
| 16 |
+
"preserve_thinking": true
|
| 17 |
+
},
|
| 18 |
+
"forced_ct_kwargs": [
|
| 19 |
+
"enable_thinking",
|
| 20 |
+
"preserve_thinking"
|
| 21 |
+
],
|
| 22 |
+
"model_type_override": "llm",
|
| 23 |
+
"enable_thinking": true,
|
| 24 |
+
"preserve_thinking": true,
|
| 25 |
+
"reasoning_parser": "qwen",
|
| 26 |
+
"turboquant_kv_enabled": false,
|
| 27 |
+
"qwen35_ane_prefill_enabled": false,
|
| 28 |
+
"specprefill_enabled": false,
|
| 29 |
+
"dflash_enabled": false,
|
| 30 |
+
"mtp_enabled": true,
|
| 31 |
+
"mtp_num_draft_tokens": 1,
|
| 32 |
+
"vlm_mtp_enabled": false,
|
| 33 |
+
"is_pinned": false,
|
| 34 |
+
"is_default": true,
|
| 35 |
+
"trust_remote_code": false,
|
| 36 |
+
"display_name": "Qwen3.8 Flash Next oQ4e MTP 128k",
|
| 37 |
+
"description": "Text-only tool-use profile with depth-1 MTP and bounded prompt priming."
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
}
|
omlx_support/qwen4_cache_integration.py
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Qwen4 cache integration for oMLX.
|
| 2 |
+
# Licensed under the Apache License 2.0. See LICENSE.
|
| 3 |
+
|
| 4 |
+
from enum import Enum
|
| 5 |
+
from typing import Any
|
| 6 |
+
|
| 7 |
+
import mlx.core as mx
|
| 8 |
+
|
| 9 |
+
from omlx.cache.type_handlers import (
|
| 10 |
+
CacheStateAxisInfo,
|
| 11 |
+
CacheTypeHandler,
|
| 12 |
+
)
|
| 13 |
+
from omlx.cache.type_registry import CacheTypeRegistry
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class Qwen4CacheType(Enum):
|
| 17 |
+
QSA_KV = "QSAKVCache"
|
| 18 |
+
QSA_QUANTIZED_KV = "QSAQuantizedKVCache"
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def _offset_from_meta(meta_state, fallback):
|
| 22 |
+
if isinstance(meta_state, (list, tuple)) and meta_state:
|
| 23 |
+
return int(meta_state[0])
|
| 24 |
+
if meta_state not in (None, ""):
|
| 25 |
+
return int(meta_state)
|
| 26 |
+
return fallback
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class QSAKVCacheHandler(CacheTypeHandler):
|
| 30 |
+
@property
|
| 31 |
+
def cache_type(self):
|
| 32 |
+
return Qwen4CacheType.QSA_KV
|
| 33 |
+
|
| 34 |
+
@property
|
| 35 |
+
def supports_block_slicing(self):
|
| 36 |
+
return True
|
| 37 |
+
|
| 38 |
+
def get_state_axis_info(self):
|
| 39 |
+
return (
|
| 40 |
+
CacheStateAxisInfo("keys", 2, True),
|
| 41 |
+
CacheStateAxisInfo("values", 2, True),
|
| 42 |
+
CacheStateAxisInfo("index_keys", 1, True),
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
def serialize_state(self, cache_obj):
|
| 46 |
+
keys, values, index_keys = cache_obj.state
|
| 47 |
+
return keys, values, index_keys
|
| 48 |
+
|
| 49 |
+
def serialize_meta_state(self, cache_obj):
|
| 50 |
+
return (int(cache_obj.offset),)
|
| 51 |
+
|
| 52 |
+
def extract_state(self, cache_obj):
|
| 53 |
+
elements = self.serialize_state(cache_obj)
|
| 54 |
+
return {
|
| 55 |
+
"keys": elements[0],
|
| 56 |
+
"values": elements[1],
|
| 57 |
+
"index_keys": elements[2],
|
| 58 |
+
"states": elements,
|
| 59 |
+
"cache_type": self.cache_type.value,
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
def get_seq_len(self, state):
|
| 63 |
+
keys = state.get("keys")
|
| 64 |
+
if keys is not None:
|
| 65 |
+
return int(keys.shape[2])
|
| 66 |
+
index_keys = state.get("index_keys")
|
| 67 |
+
return 0 if index_keys is None else int(index_keys.shape[1])
|
| 68 |
+
|
| 69 |
+
def slice_state(self, state, start_idx, end_idx):
|
| 70 |
+
keys = state.get("keys")
|
| 71 |
+
values = state.get("values")
|
| 72 |
+
index_keys = state.get("index_keys")
|
| 73 |
+
if keys is None or values is None:
|
| 74 |
+
return None
|
| 75 |
+
end_idx = min(end_idx, int(keys.shape[2]))
|
| 76 |
+
if start_idx >= end_idx:
|
| 77 |
+
return None
|
| 78 |
+
index_end = min(end_idx, int(index_keys.shape[1]))
|
| 79 |
+
elements = (
|
| 80 |
+
keys[:, :, start_idx:end_idx, :],
|
| 81 |
+
values[:, :, start_idx:end_idx, :],
|
| 82 |
+
index_keys[:, start_idx:index_end, :],
|
| 83 |
+
)
|
| 84 |
+
return {
|
| 85 |
+
"keys": elements[0],
|
| 86 |
+
"values": elements[1],
|
| 87 |
+
"index_keys": elements[2],
|
| 88 |
+
"states": elements,
|
| 89 |
+
"cache_type": self.cache_type.value,
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
def concatenate_states(self, states):
|
| 93 |
+
elements = [state.get("states") for state in states]
|
| 94 |
+
elements = [value for value in elements if value]
|
| 95 |
+
if not elements:
|
| 96 |
+
return {}
|
| 97 |
+
combined = (
|
| 98 |
+
mx.concatenate([value[0] for value in elements], axis=2),
|
| 99 |
+
mx.concatenate([value[1] for value in elements], axis=2),
|
| 100 |
+
mx.concatenate([value[2] for value in elements], axis=1),
|
| 101 |
+
)
|
| 102 |
+
return {
|
| 103 |
+
"keys": combined[0],
|
| 104 |
+
"values": combined[1],
|
| 105 |
+
"index_keys": combined[2],
|
| 106 |
+
"states": combined,
|
| 107 |
+
"cache_type": self.cache_type.value,
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
def deserialize_state(self, elements, meta_state=None):
|
| 111 |
+
from mlx_lm.models.qwen4_exp import QSAKVCache
|
| 112 |
+
|
| 113 |
+
keys = elements[0] if len(elements) > 0 else None
|
| 114 |
+
values = elements[1] if len(elements) > 1 else None
|
| 115 |
+
index_keys = elements[2] if len(elements) > 2 else None
|
| 116 |
+
fallback = 0 if keys is None else int(keys.shape[2])
|
| 117 |
+
cache = QSAKVCache()
|
| 118 |
+
cache.keys = keys
|
| 119 |
+
cache.values = values
|
| 120 |
+
cache.index_keys = index_keys
|
| 121 |
+
cache.offset = _offset_from_meta(meta_state, fallback)
|
| 122 |
+
return cache
|
| 123 |
+
|
| 124 |
+
def reconstruct_cache(self, state, meta_state=None):
|
| 125 |
+
elements = state.get("states")
|
| 126 |
+
if elements is None:
|
| 127 |
+
elements = (
|
| 128 |
+
state.get("keys"),
|
| 129 |
+
state.get("values"),
|
| 130 |
+
state.get("index_keys"),
|
| 131 |
+
)
|
| 132 |
+
return self.deserialize_state(tuple(elements), meta_state)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
class QSAQuantizedKVCacheHandler(CacheTypeHandler):
|
| 136 |
+
@property
|
| 137 |
+
def cache_type(self):
|
| 138 |
+
return Qwen4CacheType.QSA_QUANTIZED_KV
|
| 139 |
+
|
| 140 |
+
@property
|
| 141 |
+
def supports_block_slicing(self):
|
| 142 |
+
return True
|
| 143 |
+
|
| 144 |
+
def get_state_axis_info(self):
|
| 145 |
+
return (
|
| 146 |
+
CacheStateAxisInfo("key_weight", 2, True),
|
| 147 |
+
CacheStateAxisInfo("key_scales", 2, True),
|
| 148 |
+
CacheStateAxisInfo("key_biases", 2, True),
|
| 149 |
+
CacheStateAxisInfo("value_weight", 2, True),
|
| 150 |
+
CacheStateAxisInfo("value_scales", 2, True),
|
| 151 |
+
CacheStateAxisInfo("value_biases", 2, True),
|
| 152 |
+
CacheStateAxisInfo("index_keys", 1, True),
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
def serialize_state(self, cache_obj):
|
| 156 |
+
if cache_obj.keys is None:
|
| 157 |
+
return (None,) * 7
|
| 158 |
+
offset = int(cache_obj.offset)
|
| 159 |
+
keys = tuple(value[:, :, :offset, :] for value in cache_obj.keys)
|
| 160 |
+
values = tuple(value[:, :, :offset, :] for value in cache_obj.values)
|
| 161 |
+
index_keys = cache_obj.index_keys
|
| 162 |
+
if index_keys is not None:
|
| 163 |
+
index_keys = index_keys[:, :offset, :]
|
| 164 |
+
return (*keys, *values, index_keys)
|
| 165 |
+
|
| 166 |
+
def serialize_meta_state(self, cache_obj):
|
| 167 |
+
return (
|
| 168 |
+
int(cache_obj.offset),
|
| 169 |
+
int(cache_obj.group_size),
|
| 170 |
+
int(cache_obj.bits),
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
def extract_state(self, cache_obj):
|
| 174 |
+
elements = self.serialize_state(cache_obj)
|
| 175 |
+
return {
|
| 176 |
+
"states": elements,
|
| 177 |
+
"keys": elements[0],
|
| 178 |
+
"values": elements[3],
|
| 179 |
+
"index_keys": elements[6],
|
| 180 |
+
"cache_type": self.cache_type.value,
|
| 181 |
+
}
|
| 182 |
+
|
| 183 |
+
def get_seq_len(self, state):
|
| 184 |
+
keys = state.get("keys")
|
| 185 |
+
if keys is not None:
|
| 186 |
+
return int(keys.shape[2])
|
| 187 |
+
index_keys = state.get("index_keys")
|
| 188 |
+
return 0 if index_keys is None else int(index_keys.shape[1])
|
| 189 |
+
|
| 190 |
+
def slice_state(self, state, start_idx, end_idx):
|
| 191 |
+
elements = state.get("states")
|
| 192 |
+
if not elements or elements[0] is None:
|
| 193 |
+
return None
|
| 194 |
+
end_idx = min(end_idx, int(elements[0].shape[2]))
|
| 195 |
+
if start_idx >= end_idx:
|
| 196 |
+
return None
|
| 197 |
+
sliced = tuple(
|
| 198 |
+
value[:, :, start_idx:end_idx, :] for value in elements[:6]
|
| 199 |
+
) + (elements[6][:, start_idx:end_idx, :],)
|
| 200 |
+
return {
|
| 201 |
+
"states": sliced,
|
| 202 |
+
"keys": sliced[0],
|
| 203 |
+
"values": sliced[3],
|
| 204 |
+
"index_keys": sliced[6],
|
| 205 |
+
"cache_type": self.cache_type.value,
|
| 206 |
+
}
|
| 207 |
+
|
| 208 |
+
def concatenate_states(self, states):
|
| 209 |
+
elements = [state.get("states") for state in states]
|
| 210 |
+
elements = [value for value in elements if value and value[0] is not None]
|
| 211 |
+
if not elements:
|
| 212 |
+
return {}
|
| 213 |
+
combined = tuple(
|
| 214 |
+
mx.concatenate([value[index] for value in elements], axis=2)
|
| 215 |
+
for index in range(6)
|
| 216 |
+
) + (mx.concatenate([value[6] for value in elements], axis=1),)
|
| 217 |
+
return {
|
| 218 |
+
"states": combined,
|
| 219 |
+
"keys": combined[0],
|
| 220 |
+
"values": combined[3],
|
| 221 |
+
"index_keys": combined[6],
|
| 222 |
+
"cache_type": self.cache_type.value,
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
def deserialize_state(self, elements, meta_state=None):
|
| 226 |
+
from mlx_lm.models.qwen4_exp import QSAQuantizedKVCache
|
| 227 |
+
|
| 228 |
+
offset = _offset_from_meta(
|
| 229 |
+
meta_state,
|
| 230 |
+
0 if not elements or elements[0] is None else int(elements[0].shape[2]),
|
| 231 |
+
)
|
| 232 |
+
group_size = int(meta_state[1]) if meta_state and len(meta_state) > 1 else 64
|
| 233 |
+
bits = int(meta_state[2]) if meta_state and len(meta_state) > 2 else 4
|
| 234 |
+
cache = QSAQuantizedKVCache(group_size=group_size, bits=bits)
|
| 235 |
+
if elements and elements[0] is not None:
|
| 236 |
+
cache.keys = tuple(elements[:3])
|
| 237 |
+
cache.values = tuple(elements[3:6])
|
| 238 |
+
cache.index_keys = elements[6] if len(elements) > 6 else None
|
| 239 |
+
cache.offset = offset
|
| 240 |
+
return cache
|
| 241 |
+
|
| 242 |
+
def reconstruct_cache(self, state, meta_state=None):
|
| 243 |
+
return self.deserialize_state(tuple(state.get("states") or ()), meta_state)
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
def _batch_indices(batch_indices):
|
| 247 |
+
if hasattr(batch_indices, "tolist"):
|
| 248 |
+
return [int(value) for value in batch_indices.tolist()]
|
| 249 |
+
return [int(value) for value in batch_indices]
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def _install_single_cache_batch_methods(cache_class):
|
| 253 |
+
def filter_rows(self, batch_indices):
|
| 254 |
+
indices = _batch_indices(batch_indices)
|
| 255 |
+
if not indices:
|
| 256 |
+
self.keys = None
|
| 257 |
+
self.values = None
|
| 258 |
+
self.index_keys = None
|
| 259 |
+
self.offset = 0
|
| 260 |
+
return
|
| 261 |
+
self.keys = _map_cache_arrays(self.keys, lambda value: value[indices])
|
| 262 |
+
self.values = _map_cache_arrays(self.values, lambda value: value[indices])
|
| 263 |
+
if self.index_keys is not None:
|
| 264 |
+
self.index_keys = self.index_keys[indices]
|
| 265 |
+
|
| 266 |
+
def extract_row(self, index):
|
| 267 |
+
result = type(self).__new__(type(self))
|
| 268 |
+
result.keys = _map_cache_arrays(self.keys, lambda value: value[index : index + 1])
|
| 269 |
+
result.values = _map_cache_arrays(self.values, lambda value: value[index : index + 1])
|
| 270 |
+
result.index_keys = (
|
| 271 |
+
None
|
| 272 |
+
if self.index_keys is None
|
| 273 |
+
else self.index_keys[index : index + 1]
|
| 274 |
+
)
|
| 275 |
+
result.offset = self.offset
|
| 276 |
+
if hasattr(self, "group_size"):
|
| 277 |
+
result.group_size = self.group_size
|
| 278 |
+
result.bits = self.bits
|
| 279 |
+
return result
|
| 280 |
+
|
| 281 |
+
def extend_rows(self, other):
|
| 282 |
+
if int(self.offset) != int(other.offset):
|
| 283 |
+
raise ValueError("QSA caches can only batch rows at the same offset")
|
| 284 |
+
if hasattr(self, "group_size") and (
|
| 285 |
+
self.group_size != other.group_size or self.bits != other.bits
|
| 286 |
+
):
|
| 287 |
+
raise ValueError("quantized QSA caches must use the same layout")
|
| 288 |
+
offset = int(self.offset)
|
| 289 |
+
self.keys = _merge_cache_arrays(self.keys, other.keys, offset, 2)
|
| 290 |
+
self.values = _merge_cache_arrays(self.values, other.values, offset, 2)
|
| 291 |
+
self.index_keys = _merge_cache_arrays(
|
| 292 |
+
self.index_keys,
|
| 293 |
+
other.index_keys,
|
| 294 |
+
offset,
|
| 295 |
+
1,
|
| 296 |
+
)
|
| 297 |
+
|
| 298 |
+
@classmethod
|
| 299 |
+
def merge_rows(cls, caches):
|
| 300 |
+
caches = list(caches)
|
| 301 |
+
if not caches:
|
| 302 |
+
return cls()
|
| 303 |
+
result = caches[0].extract(0)
|
| 304 |
+
for cache in caches[1:]:
|
| 305 |
+
result.extend(cache)
|
| 306 |
+
return result
|
| 307 |
+
|
| 308 |
+
cache_class.filter = filter_rows
|
| 309 |
+
cache_class.extract = extract_row
|
| 310 |
+
cache_class.extend = extend_rows
|
| 311 |
+
cache_class.merge = merge_rows
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
def _install_quantized_state_layout(cache_class):
|
| 315 |
+
def get_state(self):
|
| 316 |
+
if self.keys is None:
|
| 317 |
+
return (None,) * 7
|
| 318 |
+
offset = int(self.offset)
|
| 319 |
+
keys = tuple(value[:, :, :offset, :] for value in self.keys)
|
| 320 |
+
values = tuple(value[:, :, :offset, :] for value in self.values)
|
| 321 |
+
index_keys = self.index_keys
|
| 322 |
+
if index_keys is not None:
|
| 323 |
+
index_keys = index_keys[:, :offset, :]
|
| 324 |
+
return (*keys, *values, index_keys)
|
| 325 |
+
|
| 326 |
+
def set_state(self, value):
|
| 327 |
+
if len(value) == 2 and isinstance(value[0], (list, tuple)):
|
| 328 |
+
quantized_state, self.index_keys = value
|
| 329 |
+
self.keys, self.values = quantized_state
|
| 330 |
+
else:
|
| 331 |
+
self.keys = tuple(value[:3]) if value and value[0] is not None else None
|
| 332 |
+
self.values = tuple(value[3:6]) if value and value[3] is not None else None
|
| 333 |
+
self.index_keys = value[6] if len(value) > 6 else None
|
| 334 |
+
self.offset = 0 if self.keys is None else int(self.keys[0].shape[2])
|
| 335 |
+
|
| 336 |
+
cache_class.state = property(get_state, set_state)
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
def _map_cache_arrays(value, function):
|
| 340 |
+
if value is None:
|
| 341 |
+
return None
|
| 342 |
+
if isinstance(value, (list, tuple)):
|
| 343 |
+
return tuple(function(item) for item in value)
|
| 344 |
+
return function(value)
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
def _merge_cache_arrays(left, right, length, sequence_axis):
|
| 348 |
+
if left is None:
|
| 349 |
+
return right
|
| 350 |
+
if right is None:
|
| 351 |
+
return left
|
| 352 |
+
if isinstance(left, (list, tuple)):
|
| 353 |
+
return tuple(
|
| 354 |
+
_merge_cache_arrays(a, b, length, sequence_axis)
|
| 355 |
+
for a, b in zip(left, right)
|
| 356 |
+
)
|
| 357 |
+
slices = [slice(None)] * left.ndim
|
| 358 |
+
slices[sequence_axis] = slice(0, length)
|
| 359 |
+
slices = tuple(slices)
|
| 360 |
+
return mx.concatenate([left[slices], right[slices]], axis=0)
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
def register_qwen4_cache_integration():
|
| 364 |
+
import mlx_lm.models.cache as mlx_cache
|
| 365 |
+
|
| 366 |
+
from mlx_lm.models.qwen4_exp import QSAKVCache, QSAQuantizedKVCache
|
| 367 |
+
|
| 368 |
+
handlers = (QSAKVCacheHandler(), QSAQuantizedKVCacheHandler())
|
| 369 |
+
for handler in handlers:
|
| 370 |
+
CacheTypeRegistry.register(handler)
|
| 371 |
+
CacheTypeRegistry._class_name_map.update(
|
| 372 |
+
{
|
| 373 |
+
QSAKVCache.__name__: Qwen4CacheType.QSA_KV,
|
| 374 |
+
QSAQuantizedKVCache.__name__: Qwen4CacheType.QSA_QUANTIZED_KV,
|
| 375 |
+
}
|
| 376 |
+
)
|
| 377 |
+
_install_single_cache_batch_methods(QSAKVCache)
|
| 378 |
+
_install_single_cache_batch_methods(QSAQuantizedKVCache)
|
| 379 |
+
_install_quantized_state_layout(QSAQuantizedKVCache)
|
| 380 |
+
mlx_cache.QSAKVCache = QSAKVCache
|
| 381 |
+
mlx_cache.QSAQuantizedKVCache = QSAQuantizedKVCache
|
omlx_support/qwen4_exp.py
ADDED
|
@@ -0,0 +1,1361 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import json
|
| 4 |
+
import logging
|
| 5 |
+
import math
|
| 6 |
+
import mmap
|
| 7 |
+
import os
|
| 8 |
+
import struct
|
| 9 |
+
from copy import copy
|
| 10 |
+
from dataclasses import dataclass, field
|
| 11 |
+
from pathlib import Path
|
| 12 |
+
from typing import Any, Dict, List, Optional
|
| 13 |
+
|
| 14 |
+
import mlx.core as mx
|
| 15 |
+
import mlx.nn as nn
|
| 16 |
+
import numpy as np
|
| 17 |
+
|
| 18 |
+
from mlx_lm.models.activations import swiglu
|
| 19 |
+
from mlx_lm.models.base import BaseModelArgs, create_ssm_mask
|
| 20 |
+
from mlx_lm.models.cache import ArraysCache, KVCache, QuantizedKVCache
|
| 21 |
+
from mlx_lm.models.gated_delta import gated_delta_update
|
| 22 |
+
from mlx_lm.models.switch_layers import SwitchGLU
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
logger = logging.getLogger(__name__)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@dataclass
|
| 29 |
+
class ModelArgs(BaseModelArgs):
|
| 30 |
+
model_type: str = "qwen4_exp"
|
| 31 |
+
vocab_size: int = 248320
|
| 32 |
+
hidden_size: int = 2048
|
| 33 |
+
num_hidden_layers: int = 40
|
| 34 |
+
mtp_num_hidden_layers: int = 0
|
| 35 |
+
num_attention_heads: int = 16
|
| 36 |
+
num_key_value_heads: int = 2
|
| 37 |
+
hidden_act: str = "silu"
|
| 38 |
+
max_position_embeddings: int = 32768
|
| 39 |
+
rms_norm_eps: float = 1e-6
|
| 40 |
+
tie_word_embeddings: bool = False
|
| 41 |
+
attention_bias: bool = False
|
| 42 |
+
attention_dropout: float = 0.0
|
| 43 |
+
head_dim: int = 256
|
| 44 |
+
linear_conv_kernel_dim: int = 4
|
| 45 |
+
linear_key_head_dim: int = 128
|
| 46 |
+
linear_value_head_dim: int = 128
|
| 47 |
+
linear_num_key_heads: int = 16
|
| 48 |
+
linear_num_value_heads: int = 32
|
| 49 |
+
moe_intermediate_size: int = 512
|
| 50 |
+
shared_expert_intermediate_size: int = 512
|
| 51 |
+
num_experts_per_tok: int = 10
|
| 52 |
+
num_experts: int = 512
|
| 53 |
+
layer_types: List[str] = field(default_factory=list)
|
| 54 |
+
hc_count: int = 4
|
| 55 |
+
hc_lowrank: int = 320
|
| 56 |
+
ple_layer_ids: List[int] = field(default_factory=list)
|
| 57 |
+
ple_embed_dim: Optional[int] = None
|
| 58 |
+
ple_conv_kernel_size: int = 4
|
| 59 |
+
ngram_size: int = 3
|
| 60 |
+
heads_per_ngram: int = 8
|
| 61 |
+
ngram_vocab_size_base: int = 20_000_000
|
| 62 |
+
make_ngram_vocab_size_divisible_by: int = 128
|
| 63 |
+
seed: int = 1234
|
| 64 |
+
split_ngram_parts: int = 512
|
| 65 |
+
indexer_n_heads: Optional[int] = None
|
| 66 |
+
indexer_kv_heads: Optional[int] = None
|
| 67 |
+
indexer_head_dim: Optional[int] = None
|
| 68 |
+
indexer_budget: Optional[int] = None
|
| 69 |
+
indexer_compress_ratio: Optional[int] = None
|
| 70 |
+
norm_topk_prob: bool = True
|
| 71 |
+
output_gate_type: Optional[str] = None
|
| 72 |
+
eos_token_id: Optional[int | List[int]] = None
|
| 73 |
+
rope_theta: float = 10000.0
|
| 74 |
+
partial_rotary_factor: float = 1.0
|
| 75 |
+
rope_parameters: Optional[Dict[str, Any]] = None
|
| 76 |
+
|
| 77 |
+
@classmethod
|
| 78 |
+
def from_dict(cls, params):
|
| 79 |
+
source = dict(params.get("text_config", params))
|
| 80 |
+
source["model_type"] = params.get("model_type", source.get("model_type", "qwen4_exp"))
|
| 81 |
+
if params.get("eos_token_id") is not None:
|
| 82 |
+
source["eos_token_id"] = params["eos_token_id"]
|
| 83 |
+
rope = source.get("rope_parameters") or {}
|
| 84 |
+
source.setdefault("rope_theta", rope.get("rope_theta", 10000.0))
|
| 85 |
+
source.setdefault("partial_rotary_factor", rope.get("partial_rotary_factor", 1.0))
|
| 86 |
+
return super().from_dict(source)
|
| 87 |
+
|
| 88 |
+
def __post_init__(self):
|
| 89 |
+
if self.ple_embed_dim is None:
|
| 90 |
+
self.ple_embed_dim = self.hidden_size
|
| 91 |
+
if not self.layer_types:
|
| 92 |
+
self.layer_types = [
|
| 93 |
+
"linear_attention" if (i + 1) % 4 else "full_attention"
|
| 94 |
+
for i in range(self.num_hidden_layers)
|
| 95 |
+
]
|
| 96 |
+
if len(self.layer_types) != self.num_hidden_layers:
|
| 97 |
+
raise ValueError("layer_types must contain one entry per hidden layer")
|
| 98 |
+
if self.hc_count <= 1:
|
| 99 |
+
raise ValueError("hc_count must be greater than one")
|
| 100 |
+
if self.linear_num_value_heads % self.linear_num_key_heads:
|
| 101 |
+
raise ValueError("linear value heads must be divisible by key heads")
|
| 102 |
+
if not 0 < self.num_experts_per_tok <= self.num_experts:
|
| 103 |
+
raise ValueError("num_experts_per_tok must select existing experts")
|
| 104 |
+
if any(layer < 1 or layer > self.num_hidden_layers for layer in self.ple_layer_ids):
|
| 105 |
+
raise ValueError("PLE layer ids are one-indexed hidden-layer ids")
|
| 106 |
+
if self.ple_layer_ids and self.eos_token_id is None:
|
| 107 |
+
raise ValueError("PLE requires eos_token_id")
|
| 108 |
+
qsa = (
|
| 109 |
+
self.indexer_n_heads,
|
| 110 |
+
self.indexer_kv_heads,
|
| 111 |
+
self.indexer_head_dim,
|
| 112 |
+
self.indexer_budget,
|
| 113 |
+
self.indexer_compress_ratio,
|
| 114 |
+
)
|
| 115 |
+
if any(value is None for value in qsa):
|
| 116 |
+
raise ValueError("QSA requires every indexer field")
|
| 117 |
+
if self.indexer_kv_heads != 1:
|
| 118 |
+
raise ValueError("QSA requires one indexer key head")
|
| 119 |
+
if self.indexer_budget % self.indexer_compress_ratio:
|
| 120 |
+
raise ValueError("indexer_budget must divide into complete compressed blocks")
|
| 121 |
+
ngram_heads = (self.ngram_size - 1) * self.heads_per_ngram
|
| 122 |
+
if self.ple_layer_ids and self.ple_embed_dim % ngram_heads:
|
| 123 |
+
raise ValueError("ple_embed_dim must be divisible by its n-gram heads")
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
class Qwen4RMSNorm(nn.Module):
|
| 127 |
+
def __init__(self, dim: int, eps: float, group_size: Optional[int] = None):
|
| 128 |
+
super().__init__()
|
| 129 |
+
self.weight = mx.zeros(dim)
|
| 130 |
+
self.eps = eps
|
| 131 |
+
self.group_size = group_size
|
| 132 |
+
|
| 133 |
+
def __call__(self, x):
|
| 134 |
+
dtype = x.dtype
|
| 135 |
+
value = x.astype(mx.float32)
|
| 136 |
+
if self.group_size is not None:
|
| 137 |
+
value = value.reshape(*value.shape[:-1], -1, self.group_size)
|
| 138 |
+
value = value * mx.rsqrt(mx.mean(mx.square(value), axis=-1, keepdims=True) + self.eps)
|
| 139 |
+
if self.group_size is not None:
|
| 140 |
+
value = value.reshape(*x.shape)
|
| 141 |
+
return (value * (1.0 + self.weight.astype(mx.float32))).astype(dtype)
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
class Qwen4RMSNormGated(nn.Module):
|
| 145 |
+
def __init__(self, dim: int, eps: float, activation: str):
|
| 146 |
+
super().__init__()
|
| 147 |
+
self.weight = mx.ones(dim)
|
| 148 |
+
self.eps = eps
|
| 149 |
+
self.activation = activation
|
| 150 |
+
|
| 151 |
+
def __call__(self, x, gate):
|
| 152 |
+
dtype = x.dtype
|
| 153 |
+
value = mx.fast.rms_norm(x, self.weight, self.eps)
|
| 154 |
+
gate = gate.astype(mx.float32)
|
| 155 |
+
gate = mx.sigmoid(gate) if self.activation == "sigmoid" else nn.silu(gate)
|
| 156 |
+
return (value.astype(mx.float32) * gate).astype(dtype)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def _l2_normalize(x, eps=1e-6):
|
| 160 |
+
return x * mx.rsqrt(mx.sum(x * x, axis=-1, keepdims=True) + eps)
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def _apply_rope(x, positions, rotary_dim: int, theta: float):
|
| 164 |
+
if rotary_dim == 0:
|
| 165 |
+
return x
|
| 166 |
+
dtype = x.dtype
|
| 167 |
+
inv_freq = theta ** (-mx.arange(0, rotary_dim, 2, dtype=mx.float32) / rotary_dim)
|
| 168 |
+
angles = positions.astype(mx.float32)[..., None] * inv_freq
|
| 169 |
+
cos = mx.concatenate([mx.cos(angles), mx.cos(angles)], axis=-1)
|
| 170 |
+
sin = mx.concatenate([mx.sin(angles), mx.sin(angles)], axis=-1)
|
| 171 |
+
while cos.ndim < x.ndim:
|
| 172 |
+
cos = mx.expand_dims(cos, axis=-2)
|
| 173 |
+
sin = mx.expand_dims(sin, axis=-2)
|
| 174 |
+
rotated, remainder = x[..., :rotary_dim], x[..., rotary_dim:]
|
| 175 |
+
first, second = mx.split(rotated, 2, axis=-1)
|
| 176 |
+
rotated = rotated * cos + mx.concatenate([-second, first], axis=-1) * sin
|
| 177 |
+
return mx.concatenate([rotated, remainder], axis=-1).astype(dtype)
|
| 178 |
+
|
| 179 |
+
|
| 180 |
+
class QSAKVCache(KVCache):
|
| 181 |
+
def __init__(self):
|
| 182 |
+
super().__init__()
|
| 183 |
+
self.index_keys = None
|
| 184 |
+
|
| 185 |
+
def update_indexer(self, keys):
|
| 186 |
+
previous = self.offset
|
| 187 |
+
length = keys.shape[1]
|
| 188 |
+
end = previous + length
|
| 189 |
+
if self.index_keys is None or end > self.index_keys.shape[1]:
|
| 190 |
+
batch, _, head_dim = keys.shape
|
| 191 |
+
steps = (self.step + length - 1) // self.step
|
| 192 |
+
extension = mx.zeros(
|
| 193 |
+
(batch, steps * self.step, head_dim),
|
| 194 |
+
dtype=keys.dtype,
|
| 195 |
+
)
|
| 196 |
+
if self.index_keys is None:
|
| 197 |
+
self.index_keys = extension
|
| 198 |
+
else:
|
| 199 |
+
if previous % self.step:
|
| 200 |
+
self.index_keys = self.index_keys[:, :previous, :]
|
| 201 |
+
self.index_keys = mx.concatenate([self.index_keys, extension], axis=1)
|
| 202 |
+
self.index_keys[:, previous:end, :] = keys
|
| 203 |
+
return self.index_keys[:, :end, :]
|
| 204 |
+
|
| 205 |
+
@property
|
| 206 |
+
def state(self):
|
| 207 |
+
index_state = (
|
| 208 |
+
self.index_keys
|
| 209 |
+
if self.index_keys is None
|
| 210 |
+
else self.index_keys[:, : self.offset, :]
|
| 211 |
+
)
|
| 212 |
+
if self.keys is None:
|
| 213 |
+
return self.keys, self.values, index_state
|
| 214 |
+
return (
|
| 215 |
+
self.keys[..., : self.offset, :],
|
| 216 |
+
self.values[..., : self.offset, :],
|
| 217 |
+
index_state,
|
| 218 |
+
)
|
| 219 |
+
|
| 220 |
+
@state.setter
|
| 221 |
+
def state(self, value):
|
| 222 |
+
self.keys, self.values, self.index_keys = value
|
| 223 |
+
self.offset = 0 if self.keys is None else self.keys.shape[2]
|
| 224 |
+
|
| 225 |
+
def trim(self, count):
|
| 226 |
+
return super().trim(count)
|
| 227 |
+
|
| 228 |
+
def to_quantized(self, group_size=64, bits=4):
|
| 229 |
+
cache = QSAQuantizedKVCache(group_size=group_size, bits=bits)
|
| 230 |
+
cache.offset = self.offset
|
| 231 |
+
cache.index_keys = self.index_keys
|
| 232 |
+
if self.keys is not None:
|
| 233 |
+
cache.keys = mx.quantize(self.keys[..., : self.offset, :], group_size=group_size, bits=bits)
|
| 234 |
+
cache.values = mx.quantize(self.values[..., : self.offset, :], group_size=group_size, bits=bits)
|
| 235 |
+
return cache
|
| 236 |
+
|
| 237 |
+
@property
|
| 238 |
+
def nbytes(self):
|
| 239 |
+
size = super().nbytes
|
| 240 |
+
return size + (0 if self.index_keys is None else self.index_keys.nbytes)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
class QSAQuantizedKVCache(QuantizedKVCache):
|
| 244 |
+
def __init__(self, group_size=64, bits=4):
|
| 245 |
+
super().__init__(group_size=group_size, bits=bits)
|
| 246 |
+
self.index_keys = None
|
| 247 |
+
|
| 248 |
+
def update_indexer(self, keys):
|
| 249 |
+
previous = self.offset
|
| 250 |
+
length = keys.shape[1]
|
| 251 |
+
end = previous + length
|
| 252 |
+
if self.index_keys is None or end > self.index_keys.shape[1]:
|
| 253 |
+
batch, _, head_dim = keys.shape
|
| 254 |
+
steps = (self.step + length - 1) // self.step
|
| 255 |
+
extension = mx.zeros(
|
| 256 |
+
(batch, steps * self.step, head_dim),
|
| 257 |
+
dtype=keys.dtype,
|
| 258 |
+
)
|
| 259 |
+
if self.index_keys is None:
|
| 260 |
+
self.index_keys = extension
|
| 261 |
+
else:
|
| 262 |
+
if previous % self.step:
|
| 263 |
+
self.index_keys = self.index_keys[:, :previous, :]
|
| 264 |
+
self.index_keys = mx.concatenate([self.index_keys, extension], axis=1)
|
| 265 |
+
self.index_keys[:, previous:end, :] = keys
|
| 266 |
+
return self.index_keys[:, :end, :]
|
| 267 |
+
|
| 268 |
+
@property
|
| 269 |
+
def state(self):
|
| 270 |
+
quantized_state = (self.keys, self.values) if self.keys is None else super().state
|
| 271 |
+
index_state = (
|
| 272 |
+
self.index_keys
|
| 273 |
+
if self.index_keys is None
|
| 274 |
+
else self.index_keys[:, : self.offset, :]
|
| 275 |
+
)
|
| 276 |
+
return quantized_state, index_state
|
| 277 |
+
|
| 278 |
+
@state.setter
|
| 279 |
+
def state(self, value):
|
| 280 |
+
quantized_state, self.index_keys = value
|
| 281 |
+
QuantizedKVCache.state.fset(self, quantized_state)
|
| 282 |
+
self.offset = 0 if self.keys is None else self.keys[0].shape[2]
|
| 283 |
+
|
| 284 |
+
def trim(self, count):
|
| 285 |
+
return super().trim(count)
|
| 286 |
+
|
| 287 |
+
def to_quantized(self, group_size=64, bits=4):
|
| 288 |
+
if group_size == self.group_size and bits == self.bits:
|
| 289 |
+
return self
|
| 290 |
+
raise ValueError("QSA KV cache is already quantized")
|
| 291 |
+
|
| 292 |
+
@property
|
| 293 |
+
def nbytes(self):
|
| 294 |
+
size = super().nbytes
|
| 295 |
+
return size + (0 if self.index_keys is None else self.index_keys.nbytes)
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
class Qwen4GatedDeltaNet(nn.Module):
|
| 299 |
+
def __init__(self, args: ModelArgs):
|
| 300 |
+
super().__init__()
|
| 301 |
+
self.num_v_heads = args.linear_num_value_heads
|
| 302 |
+
self.num_k_heads = args.linear_num_key_heads
|
| 303 |
+
self.head_k_dim = args.linear_key_head_dim
|
| 304 |
+
self.head_v_dim = args.linear_value_head_dim
|
| 305 |
+
self.key_dim = self.num_k_heads * self.head_k_dim
|
| 306 |
+
self.value_dim = self.num_v_heads * self.head_v_dim
|
| 307 |
+
self.conv_kernel_size = args.linear_conv_kernel_dim
|
| 308 |
+
self.conv_dim = 2 * self.key_dim + self.value_dim
|
| 309 |
+
self.conv1d = nn.Conv1d(
|
| 310 |
+
self.conv_dim,
|
| 311 |
+
self.conv_dim,
|
| 312 |
+
self.conv_kernel_size,
|
| 313 |
+
groups=self.conv_dim,
|
| 314 |
+
bias=False,
|
| 315 |
+
)
|
| 316 |
+
self.in_proj_qkv = nn.Linear(args.hidden_size, self.conv_dim, bias=False)
|
| 317 |
+
self.in_proj_z = nn.Linear(args.hidden_size, self.value_dim, bias=False)
|
| 318 |
+
self.in_proj_b = nn.Linear(args.hidden_size, self.num_v_heads, bias=False)
|
| 319 |
+
self.in_proj_a = nn.Linear(args.hidden_size, self.num_v_heads, bias=False)
|
| 320 |
+
self.dt_bias = mx.ones(self.num_v_heads)
|
| 321 |
+
self.A_log = mx.log(mx.random.uniform(low=0.01, high=16.0, shape=(self.num_v_heads,)))
|
| 322 |
+
self.norm = Qwen4RMSNormGated(
|
| 323 |
+
self.head_v_dim,
|
| 324 |
+
args.rms_norm_eps,
|
| 325 |
+
args.output_gate_type or args.hidden_act,
|
| 326 |
+
)
|
| 327 |
+
self.out_proj = nn.Linear(self.value_dim, args.hidden_size, bias=False)
|
| 328 |
+
|
| 329 |
+
def _process_chunk(self, mixed, a, b, conv_state, state, mask=None):
|
| 330 |
+
batch, length = mixed.shape[:2]
|
| 331 |
+
conv_input = mx.concatenate([conv_state, mixed], axis=1)
|
| 332 |
+
next_conv_state = mx.contiguous(
|
| 333 |
+
conv_input[:, -(self.conv_kernel_size - 1) :, :]
|
| 334 |
+
)
|
| 335 |
+
mixed = nn.silu(self.conv1d(conv_input))
|
| 336 |
+
q, k, value = mx.split(mixed, [self.key_dim, 2 * self.key_dim], axis=-1)
|
| 337 |
+
q = q.reshape(batch, length, self.num_k_heads, self.head_k_dim)
|
| 338 |
+
k = k.reshape(batch, length, self.num_k_heads, self.head_k_dim)
|
| 339 |
+
value = value.reshape(batch, length, self.num_v_heads, self.head_v_dim)
|
| 340 |
+
q = _l2_normalize(q) * (self.head_k_dim**-0.5)
|
| 341 |
+
k = _l2_normalize(k)
|
| 342 |
+
output, state = gated_delta_update(
|
| 343 |
+
q,
|
| 344 |
+
k,
|
| 345 |
+
value,
|
| 346 |
+
a.astype(mx.float32),
|
| 347 |
+
b,
|
| 348 |
+
self.A_log,
|
| 349 |
+
self.dt_bias,
|
| 350 |
+
state,
|
| 351 |
+
mask,
|
| 352 |
+
use_kernel=not self.training,
|
| 353 |
+
)
|
| 354 |
+
return output, next_conv_state, state
|
| 355 |
+
|
| 356 |
+
def __call__(self, x, mask=None, cache=None, n_confirmed=0):
|
| 357 |
+
batch, length, _ = x.shape
|
| 358 |
+
mixed = self.in_proj_qkv(x)
|
| 359 |
+
z = self.in_proj_z(x).reshape(batch, length, self.num_v_heads, self.head_v_dim)
|
| 360 |
+
b = self.in_proj_b(x)
|
| 361 |
+
a = self.in_proj_a(x)
|
| 362 |
+
if mask is not None:
|
| 363 |
+
mixed = mx.where(mask[..., None], mixed, 0)
|
| 364 |
+
if cache is not None and cache[0] is not None:
|
| 365 |
+
conv_state = cache[0]
|
| 366 |
+
else:
|
| 367 |
+
conv_state = mx.zeros((batch, self.conv_kernel_size - 1, self.conv_dim), dtype=x.dtype)
|
| 368 |
+
state = None if cache is None else cache[1]
|
| 369 |
+
output, next_conv_state, next_state = self._process_chunk(
|
| 370 |
+
mixed,
|
| 371 |
+
a,
|
| 372 |
+
b,
|
| 373 |
+
conv_state,
|
| 374 |
+
state,
|
| 375 |
+
mask,
|
| 376 |
+
)
|
| 377 |
+
if cache is not None:
|
| 378 |
+
cache[0] = next_conv_state
|
| 379 |
+
cache[1] = next_state
|
| 380 |
+
if 0 < n_confirmed < length:
|
| 381 |
+
cache.rollback_state = (conv_state, state)
|
| 382 |
+
cache._mtp_draft_stash = (mixed, a, b, mask)
|
| 383 |
+
cache.advance(length)
|
| 384 |
+
output = self.norm(output, z).reshape(batch, length, -1)
|
| 385 |
+
return self.out_proj(output)
|
| 386 |
+
|
| 387 |
+
|
| 388 |
+
class Qwen4QSAIndexer(nn.Module):
|
| 389 |
+
def __init__(self, args: ModelArgs):
|
| 390 |
+
super().__init__()
|
| 391 |
+
self.n_heads = args.indexer_n_heads
|
| 392 |
+
self.head_dim = args.indexer_head_dim
|
| 393 |
+
self.budget = args.indexer_budget
|
| 394 |
+
self.compress_ratio = args.indexer_compress_ratio
|
| 395 |
+
self.block_topk = self.budget // self.compress_ratio
|
| 396 |
+
self.rotary_dim = int(args.head_dim * args.partial_rotary_factor)
|
| 397 |
+
self.rope_theta = args.rope_theta
|
| 398 |
+
self.index_qk_proj = nn.Linear(
|
| 399 |
+
args.hidden_size,
|
| 400 |
+
(args.indexer_n_heads + args.indexer_kv_heads) * args.indexer_head_dim,
|
| 401 |
+
bias=False,
|
| 402 |
+
)
|
| 403 |
+
self.q_layernorm = Qwen4RMSNorm(self.head_dim, args.rms_norm_eps)
|
| 404 |
+
self.k_layernorm = Qwen4RMSNorm(self.head_dim, args.rms_norm_eps)
|
| 405 |
+
|
| 406 |
+
def __call__(self, hidden_states, cache, offset):
|
| 407 |
+
batch, length, _ = hidden_states.shape
|
| 408 |
+
qk = self.index_qk_proj(hidden_states)
|
| 409 |
+
split = self.n_heads * self.head_dim
|
| 410 |
+
query, raw_keys = mx.split(qk, [split], axis=-1)
|
| 411 |
+
query = self.q_layernorm(query.reshape(batch, length, self.n_heads, self.head_dim))
|
| 412 |
+
raw_keys = raw_keys.reshape(batch, length, self.head_dim)
|
| 413 |
+
raw_keys = cache.update_indexer(raw_keys) if cache is not None else raw_keys
|
| 414 |
+
positions = offset + mx.arange(length)
|
| 415 |
+
query = _apply_rope(query, positions[None], self.rotary_dim, self.rope_theta)
|
| 416 |
+
return query, raw_keys, positions
|
| 417 |
+
|
| 418 |
+
def select(self, query, raw_keys, positions):
|
| 419 |
+
batch, length, _, _ = query.shape
|
| 420 |
+
key_length = raw_keys.shape[1]
|
| 421 |
+
ratio = self.compress_ratio
|
| 422 |
+
block_count = key_length // ratio
|
| 423 |
+
selected_parts = []
|
| 424 |
+
valid_parts = []
|
| 425 |
+
if block_count:
|
| 426 |
+
pooled = raw_keys[:, : block_count * ratio].reshape(
|
| 427 |
+
batch, block_count, ratio, self.head_dim
|
| 428 |
+
).mean(axis=2)
|
| 429 |
+
pooled = self.k_layernorm(pooled)
|
| 430 |
+
block_positions = mx.arange(block_count) * ratio
|
| 431 |
+
pooled = _apply_rope(
|
| 432 |
+
pooled,
|
| 433 |
+
block_positions[None],
|
| 434 |
+
self.rotary_dim,
|
| 435 |
+
self.rope_theta,
|
| 436 |
+
)
|
| 437 |
+
scores = mx.einsum(
|
| 438 |
+
"blhd,bkd->blhk",
|
| 439 |
+
query.astype(mx.float32),
|
| 440 |
+
pooled.astype(mx.float32),
|
| 441 |
+
)
|
| 442 |
+
scores = mx.sum(mx.maximum(scores, 0), axis=2) / math.sqrt(self.head_dim)
|
| 443 |
+
complete = (positions + 1) // ratio
|
| 444 |
+
block_valid = mx.arange(block_count)[None, None, :] < complete[None, :, None]
|
| 445 |
+
scores = mx.where(block_valid, scores, mx.finfo(scores.dtype).min)
|
| 446 |
+
take = min(self.block_topk, block_count)
|
| 447 |
+
if take == block_count:
|
| 448 |
+
selected_blocks = mx.broadcast_to(
|
| 449 |
+
mx.arange(block_count)[None, None, :],
|
| 450 |
+
(batch, length, block_count),
|
| 451 |
+
)
|
| 452 |
+
else:
|
| 453 |
+
selected_blocks = mx.argpartition(scores, kth=block_count - take, axis=-1)[..., -take:]
|
| 454 |
+
chosen_valid = mx.take_along_axis(block_valid, selected_blocks, axis=-1)
|
| 455 |
+
selected_parts.append(
|
| 456 |
+
(selected_blocks[..., None] * ratio + mx.arange(ratio)).reshape(batch, length, -1)
|
| 457 |
+
)
|
| 458 |
+
valid_parts.append(
|
| 459 |
+
mx.broadcast_to(chosen_valid[..., None], (*chosen_valid.shape, ratio)).reshape(batch, length, -1)
|
| 460 |
+
)
|
| 461 |
+
tail_width = max(ratio - 1, 1)
|
| 462 |
+
tail_start = ((positions + 1) // ratio) * ratio
|
| 463 |
+
tail = tail_start[:, None] + mx.arange(tail_width)[None]
|
| 464 |
+
tail_valid = tail <= positions[:, None]
|
| 465 |
+
selected_parts.append(mx.broadcast_to(tail[None], (batch, length, tail_width)))
|
| 466 |
+
valid_parts.append(mx.broadcast_to(tail_valid[None], (batch, length, tail_width)))
|
| 467 |
+
return mx.concatenate(selected_parts, axis=-1), mx.concatenate(valid_parts, axis=-1)
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
class Qwen4Attention(nn.Module):
|
| 471 |
+
def __init__(self, args: ModelArgs):
|
| 472 |
+
super().__init__()
|
| 473 |
+
self.num_heads = args.num_attention_heads
|
| 474 |
+
self.num_kv_heads = args.num_key_value_heads
|
| 475 |
+
self.head_dim = args.head_dim
|
| 476 |
+
self.repeats = self.num_heads // self.num_kv_heads
|
| 477 |
+
self.scale = self.head_dim**-0.5
|
| 478 |
+
self.rotary_dim = int(self.head_dim * args.partial_rotary_factor)
|
| 479 |
+
self.rope_theta = args.rope_theta
|
| 480 |
+
self.q_proj = nn.Linear(args.hidden_size, self.num_heads * self.head_dim * 2, bias=args.attention_bias)
|
| 481 |
+
self.k_proj = nn.Linear(args.hidden_size, self.num_kv_heads * self.head_dim, bias=args.attention_bias)
|
| 482 |
+
self.v_proj = nn.Linear(args.hidden_size, self.num_kv_heads * self.head_dim, bias=args.attention_bias)
|
| 483 |
+
self.o_proj = nn.Linear(self.num_heads * self.head_dim, args.hidden_size, bias=args.attention_bias)
|
| 484 |
+
self.q_norm = Qwen4RMSNorm(self.head_dim, args.rms_norm_eps)
|
| 485 |
+
self.k_norm = Qwen4RMSNorm(self.head_dim, args.rms_norm_eps)
|
| 486 |
+
self.indexer = Qwen4QSAIndexer(args)
|
| 487 |
+
|
| 488 |
+
def _select_cache_rows(self, values, batch_index, indices, cache):
|
| 489 |
+
if not isinstance(values, (list, tuple)):
|
| 490 |
+
return values[batch_index, :, indices, :].transpose(2, 0, 1, 3)
|
| 491 |
+
parts = [value[batch_index, :, indices, :].transpose(2, 0, 1, 3) for value in values]
|
| 492 |
+
return mx.dequantize(
|
| 493 |
+
parts[0],
|
| 494 |
+
parts[1],
|
| 495 |
+
parts[2],
|
| 496 |
+
group_size=cache.group_size,
|
| 497 |
+
bits=cache.bits,
|
| 498 |
+
)
|
| 499 |
+
|
| 500 |
+
def _sparse_attention(self, query, keys, values, selected, valid, cache):
|
| 501 |
+
outputs = []
|
| 502 |
+
for batch_index in range(query.shape[0]):
|
| 503 |
+
grouped_query = query[batch_index].reshape(
|
| 504 |
+
self.num_kv_heads, self.repeats, query.shape[2], self.head_dim
|
| 505 |
+
)
|
| 506 |
+
chunks = []
|
| 507 |
+
for start in range(0, query.shape[2], 64):
|
| 508 |
+
end = min(start + 64, query.shape[2])
|
| 509 |
+
key_length = (
|
| 510 |
+
keys[0].shape[2]
|
| 511 |
+
if isinstance(keys, (list, tuple))
|
| 512 |
+
else keys.shape[2]
|
| 513 |
+
)
|
| 514 |
+
indices = mx.clip(
|
| 515 |
+
selected[batch_index, start:end],
|
| 516 |
+
0,
|
| 517 |
+
key_length - 1,
|
| 518 |
+
)
|
| 519 |
+
selected_keys = self._select_cache_rows(keys, batch_index, indices, cache)
|
| 520 |
+
selected_values = self._select_cache_rows(values, batch_index, indices, cache)
|
| 521 |
+
local_query = grouped_query[:, :, start:end]
|
| 522 |
+
scores = mx.einsum("hrld,hlmd->hrlm", local_query, selected_keys) * self.scale
|
| 523 |
+
scores = mx.where(valid[batch_index, start:end][None, None], scores, mx.finfo(scores.dtype).min)
|
| 524 |
+
probabilities = mx.softmax(scores, axis=-1, precise=True)
|
| 525 |
+
output = mx.einsum("hrlm,hlmd->hrld", probabilities, selected_values)
|
| 526 |
+
mx.eval(output)
|
| 527 |
+
chunks.append(output)
|
| 528 |
+
output = mx.concatenate(chunks, axis=2)
|
| 529 |
+
outputs.append(output.reshape(self.num_heads, query.shape[2], self.head_dim)[None])
|
| 530 |
+
return mx.concatenate(outputs, axis=0)
|
| 531 |
+
|
| 532 |
+
def __call__(self, x, cache=None):
|
| 533 |
+
batch, length, _ = x.shape
|
| 534 |
+
offset = 0 if cache is None else cache.offset
|
| 535 |
+
projected = self.q_proj(x).reshape(batch, length, self.num_heads, 2 * self.head_dim)
|
| 536 |
+
query, gate = mx.split(projected, 2, axis=-1)
|
| 537 |
+
gate = gate.reshape(batch, length, -1)
|
| 538 |
+
keys = self.k_proj(x).reshape(batch, length, self.num_kv_heads, self.head_dim)
|
| 539 |
+
values = self.v_proj(x).reshape(batch, length, self.num_kv_heads, self.head_dim)
|
| 540 |
+
positions = offset + mx.arange(length)
|
| 541 |
+
query = _apply_rope(self.q_norm(query), positions[None], self.rotary_dim, self.rope_theta)
|
| 542 |
+
keys = _apply_rope(self.k_norm(keys), positions[None], self.rotary_dim, self.rope_theta)
|
| 543 |
+
query = query.transpose(0, 2, 1, 3)
|
| 544 |
+
keys = keys.transpose(0, 2, 1, 3)
|
| 545 |
+
values = values.transpose(0, 2, 1, 3)
|
| 546 |
+
index_query, raw_keys, _ = self.indexer(x, cache, offset)
|
| 547 |
+
if cache is not None:
|
| 548 |
+
keys, values = cache.update_and_fetch(keys, values)
|
| 549 |
+
selected, valid = self.indexer.select(index_query, raw_keys, positions)
|
| 550 |
+
output = self._sparse_attention(query, keys, values, selected, valid, cache)
|
| 551 |
+
output = output.transpose(0, 2, 1, 3).reshape(batch, length, -1)
|
| 552 |
+
return self.o_proj(output * mx.sigmoid(gate))
|
| 553 |
+
|
| 554 |
+
|
| 555 |
+
class Qwen4MLP(nn.Module):
|
| 556 |
+
def __init__(self, dim, hidden_dim):
|
| 557 |
+
super().__init__()
|
| 558 |
+
self.gate_proj = nn.Linear(dim, hidden_dim, bias=False)
|
| 559 |
+
self.up_proj = nn.Linear(dim, hidden_dim, bias=False)
|
| 560 |
+
self.down_proj = nn.Linear(hidden_dim, dim, bias=False)
|
| 561 |
+
|
| 562 |
+
def __call__(self, x):
|
| 563 |
+
return self.down_proj(swiglu(self.gate_proj(x), self.up_proj(x)))
|
| 564 |
+
|
| 565 |
+
|
| 566 |
+
class Qwen4SparseMoeBlock(nn.Module):
|
| 567 |
+
def __init__(self, args: ModelArgs):
|
| 568 |
+
super().__init__()
|
| 569 |
+
self.top_k = args.num_experts_per_tok
|
| 570 |
+
self.norm_topk_prob = args.norm_topk_prob
|
| 571 |
+
self.gate = nn.Linear(args.hidden_size, args.num_experts, bias=False)
|
| 572 |
+
self.switch_mlp = SwitchGLU(args.hidden_size, args.moe_intermediate_size, args.num_experts)
|
| 573 |
+
self.shared_expert = Qwen4MLP(args.hidden_size, args.shared_expert_intermediate_size)
|
| 574 |
+
self.shared_expert_gate = nn.Linear(args.hidden_size, 1, bias=False)
|
| 575 |
+
|
| 576 |
+
def _routing_weights(self, router_logits):
|
| 577 |
+
gates = mx.softmax(router_logits.astype(mx.float32), axis=-1, precise=True)
|
| 578 |
+
indices = mx.argpartition(gates, kth=-self.top_k, axis=-1)[..., -self.top_k :]
|
| 579 |
+
scores = mx.take_along_axis(gates, indices, axis=-1)
|
| 580 |
+
if self.norm_topk_prob:
|
| 581 |
+
scores = scores / mx.sum(scores, axis=-1, keepdims=True)
|
| 582 |
+
return scores.astype(router_logits.dtype), indices
|
| 583 |
+
|
| 584 |
+
def __call__(self, x):
|
| 585 |
+
scores, indices = self._routing_weights(self.gate(x))
|
| 586 |
+
routed = mx.sum(self.switch_mlp(x, indices) * scores[..., None], axis=-2)
|
| 587 |
+
shared = mx.sigmoid(self.shared_expert_gate(x)) * self.shared_expert(x)
|
| 588 |
+
return routed + shared
|
| 589 |
+
|
| 590 |
+
|
| 591 |
+
class Qwen4GatedResidual(nn.Module):
|
| 592 |
+
def __init__(self, args: ModelArgs, combine=True):
|
| 593 |
+
super().__init__()
|
| 594 |
+
self.hc_count = args.hc_count
|
| 595 |
+
self.hidden_size = args.hidden_size
|
| 596 |
+
total = self.hc_count * self.hidden_size
|
| 597 |
+
self.hc_norm = Qwen4RMSNorm(total, args.rms_norm_eps, group_size=self.hidden_size)
|
| 598 |
+
self.input_mix_weight_down = nn.Linear(total, args.hc_lowrank, bias=False)
|
| 599 |
+
self.input_mix_weight_up = nn.Linear(args.hc_lowrank, total, bias=False)
|
| 600 |
+
self.block_inject_weight = nn.Linear(total, self.hc_count, bias=False) if combine else None
|
| 601 |
+
|
| 602 |
+
def __call__(self, x):
|
| 603 |
+
normalized = self.hc_norm(x)
|
| 604 |
+
weights = nn.silu(self.input_mix_weight_down(normalized) / self.hc_count)
|
| 605 |
+
weights = mx.sigmoid(self.input_mix_weight_up(weights)).reshape(
|
| 606 |
+
*x.shape[:-1], self.hc_count, self.hidden_size
|
| 607 |
+
)
|
| 608 |
+
mixed = mx.mean(
|
| 609 |
+
weights * normalized.reshape(*x.shape[:-1], self.hc_count, self.hidden_size),
|
| 610 |
+
axis=-2,
|
| 611 |
+
)
|
| 612 |
+
if self.block_inject_weight is None:
|
| 613 |
+
return mixed
|
| 614 |
+
injection = 2 * mx.sigmoid(self.block_inject_weight(normalized) / self.hc_count)
|
| 615 |
+
return mixed, x, injection
|
| 616 |
+
|
| 617 |
+
|
| 618 |
+
_MASK64 = (1 << 64) - 1
|
| 619 |
+
_SPLITMIX_GAMMA = 0x9E3779B97F4A7C15
|
| 620 |
+
_SPLITMIX_M1 = 0xBF58476D1CE4E5B9
|
| 621 |
+
_SPLITMIX_M2 = 0x94D049BB133111EB
|
| 622 |
+
|
| 623 |
+
|
| 624 |
+
def _splitmix64(value):
|
| 625 |
+
value = (value + _SPLITMIX_GAMMA) & _MASK64
|
| 626 |
+
value = ((value ^ (value >> 30)) * _SPLITMIX_M1) & _MASK64
|
| 627 |
+
value = ((value ^ (value >> 27)) * _SPLITMIX_M2) & _MASK64
|
| 628 |
+
return (value ^ (value >> 31)) & _MASK64
|
| 629 |
+
|
| 630 |
+
|
| 631 |
+
def _multipliers(vocab_size, ngram_size, layer_index, seed):
|
| 632 |
+
maximum = ((1 << 63) - 1) // max(vocab_size, 1)
|
| 633 |
+
bound = max(1, maximum // 2)
|
| 634 |
+
base = seed + 10007 * layer_index
|
| 635 |
+
return [
|
| 636 |
+
2 * (_splitmix64((base + _SPLITMIX_GAMMA * (index + 1)) & _MASK64) % bound) + 1
|
| 637 |
+
for index in range(ngram_size)
|
| 638 |
+
]
|
| 639 |
+
|
| 640 |
+
|
| 641 |
+
def _is_prime(value):
|
| 642 |
+
if value < 2:
|
| 643 |
+
return False
|
| 644 |
+
if value % 2 == 0:
|
| 645 |
+
return value == 2
|
| 646 |
+
return all(value % divisor for divisor in range(3, math.isqrt(value) + 1, 2))
|
| 647 |
+
|
| 648 |
+
|
| 649 |
+
def _nth_prime_after(start, count):
|
| 650 |
+
value = start
|
| 651 |
+
for _ in range(count):
|
| 652 |
+
value += 1
|
| 653 |
+
while not _is_prime(value):
|
| 654 |
+
value += 1
|
| 655 |
+
return value
|
| 656 |
+
|
| 657 |
+
|
| 658 |
+
class Qwen4NGramEmbedding(nn.Module):
|
| 659 |
+
def __init__(self, args: ModelArgs, layer_index: int, model_layer_index=None):
|
| 660 |
+
super().__init__()
|
| 661 |
+
self.ngram_size = args.ngram_size
|
| 662 |
+
self.context_len = self.ngram_size - 1
|
| 663 |
+
self.heads_per_ngram = args.heads_per_ngram
|
| 664 |
+
self.ngram_heads = self.context_len * self.heads_per_ngram
|
| 665 |
+
self.eos_token_id = args.eos_token_id[0] if isinstance(args.eos_token_id, list) else args.eos_token_id
|
| 666 |
+
sizes = [
|
| 667 |
+
_nth_prime_after(args.ngram_vocab_size_base - 1, head + 1)
|
| 668 |
+
for head in range(self.ngram_heads)
|
| 669 |
+
]
|
| 670 |
+
offsets = []
|
| 671 |
+
total = 0
|
| 672 |
+
for size in sizes:
|
| 673 |
+
offsets.append(total)
|
| 674 |
+
total += size
|
| 675 |
+
padded = math.ceil(total / args.make_ngram_vocab_size_divisible_by) * args.make_ngram_vocab_size_divisible_by
|
| 676 |
+
self.layer_multipliers = mx.array(
|
| 677 |
+
_multipliers(args.vocab_size, self.ngram_size, layer_index, args.seed),
|
| 678 |
+
dtype=mx.int64,
|
| 679 |
+
)
|
| 680 |
+
self.ngram_heads_vocab_sizes = mx.array(sizes, dtype=mx.int64)
|
| 681 |
+
self.ngram_heads_offsets = mx.array(offsets, dtype=mx.int64)
|
| 682 |
+
model_path = os.environ.get("OMLX_QWEN4_PLE_MODEL_PATH")
|
| 683 |
+
mode = os.environ.get("OMLX_QWEN4_PLE_MODE", "resident")
|
| 684 |
+
embedding_args = (
|
| 685 |
+
padded,
|
| 686 |
+
args.ple_embed_dim // self.ngram_heads,
|
| 687 |
+
args.split_ngram_parts,
|
| 688 |
+
)
|
| 689 |
+
if mode == "mmap":
|
| 690 |
+
if model_path is None or model_layer_index is None:
|
| 691 |
+
raise RuntimeError("SSD-backed PLE requires its model path and decoder layer index")
|
| 692 |
+
prefix = f"model.layers.{model_layer_index}.ple.ple_embedding.ngram_embedding"
|
| 693 |
+
self.ngram_embedding = DiskBackedShardedEmbedding(
|
| 694 |
+
model_path,
|
| 695 |
+
prefix,
|
| 696 |
+
*embedding_args,
|
| 697 |
+
)
|
| 698 |
+
elif mode == "resident":
|
| 699 |
+
self.ngram_embedding = ShardedEmbedding(*embedding_args)
|
| 700 |
+
else:
|
| 701 |
+
raise ValueError("OMLX_QWEN4_PLE_MODE must be resident or mmap")
|
| 702 |
+
|
| 703 |
+
def _shift(self, tokens, shift):
|
| 704 |
+
if shift == 0:
|
| 705 |
+
return tokens
|
| 706 |
+
batch, length = tokens.shape
|
| 707 |
+
positions = mx.arange(length)
|
| 708 |
+
eos_positions = mx.where(tokens == self.eos_token_id, positions[None], -1)
|
| 709 |
+
inclusive = mx.cummax(eos_positions, axis=1)
|
| 710 |
+
previous = mx.concatenate([mx.full((batch, 1), -1, dtype=mx.int64), inclusive[:, :-1]], axis=1)
|
| 711 |
+
source = positions - shift
|
| 712 |
+
gathered = tokens[:, mx.maximum(source, 0)]
|
| 713 |
+
valid = (positions[None] - previous - 1 >= shift) & (source[None] >= 0)
|
| 714 |
+
return mx.where(valid, gathered, self.eos_token_id)
|
| 715 |
+
|
| 716 |
+
def __call__(self, input_ids, cache=None):
|
| 717 |
+
input_ids = input_ids.astype(mx.int64)
|
| 718 |
+
if cache is not None and cache[3] is not None:
|
| 719 |
+
previous = cache[3]
|
| 720 |
+
else:
|
| 721 |
+
previous = mx.full((input_ids.shape[0], self.context_len), self.eos_token_id, dtype=mx.int64)
|
| 722 |
+
history = mx.concatenate([previous, input_ids], axis=1)
|
| 723 |
+
if cache is not None:
|
| 724 |
+
cache[3] = mx.contiguous(history[:, -self.context_len :])
|
| 725 |
+
shifted = [self._shift(history, shift) for shift in range(self.ngram_size)]
|
| 726 |
+
blocks = []
|
| 727 |
+
for ngram in range(2, self.ngram_size + 1):
|
| 728 |
+
start = (ngram - 2) * self.heads_per_ngram
|
| 729 |
+
end = start + self.heads_per_ngram
|
| 730 |
+
mixed = shifted[0] * self.layer_multipliers[0]
|
| 731 |
+
for position in range(1, ngram):
|
| 732 |
+
mixed = mx.bitwise_xor(mixed, shifted[position] * self.layer_multipliers[position])
|
| 733 |
+
ids = mixed[..., None] % self.ngram_heads_vocab_sizes[start:end]
|
| 734 |
+
blocks.append(ids + self.ngram_heads_offsets[start:end])
|
| 735 |
+
ids = mx.concatenate(blocks, axis=-1)[:, -input_ids.shape[1] :]
|
| 736 |
+
return self.ngram_embedding(ids).reshape(input_ids.shape[0], input_ids.shape[1], -1)
|
| 737 |
+
|
| 738 |
+
|
| 739 |
+
class ShardedEmbedding(nn.Module):
|
| 740 |
+
def __init__(self, num_embeddings, dims, shard_count):
|
| 741 |
+
super().__init__()
|
| 742 |
+
if num_embeddings % shard_count:
|
| 743 |
+
raise ValueError("the padded n-gram vocabulary must divide evenly into shards")
|
| 744 |
+
self.shard_size = num_embeddings // shard_count
|
| 745 |
+
self.dims = dims
|
| 746 |
+
self.shards = [nn.Embedding(self.shard_size, dims) for _ in range(shard_count)]
|
| 747 |
+
|
| 748 |
+
def __call__(self, ids):
|
| 749 |
+
shape = ids.shape
|
| 750 |
+
flat_ids = ids.reshape(-1)
|
| 751 |
+
if flat_ids.size == 0:
|
| 752 |
+
return self.shards[0](flat_ids).reshape(*shape, self.dims)
|
| 753 |
+
shard_ids = flat_ids // self.shard_size
|
| 754 |
+
local_ids = flat_ids % self.shard_size
|
| 755 |
+
mx.eval(shard_ids)
|
| 756 |
+
host_shards = shard_ids.tolist()
|
| 757 |
+
output = None
|
| 758 |
+
for shard_index in sorted(set(host_shards)):
|
| 759 |
+
positions = mx.array(
|
| 760 |
+
[index for index, value in enumerate(host_shards) if value == shard_index],
|
| 761 |
+
dtype=mx.int32,
|
| 762 |
+
)
|
| 763 |
+
values = self.shards[shard_index](local_ids[positions])
|
| 764 |
+
if output is None:
|
| 765 |
+
output = mx.zeros((flat_ids.size, self.dims), dtype=values.dtype)
|
| 766 |
+
output[positions] = values
|
| 767 |
+
mx.eval(output)
|
| 768 |
+
return output.reshape(*shape, self.dims)
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
_SAFETENSORS_NUMPY_DTYPES = {
|
| 772 |
+
"U32": np.dtype("<u4"),
|
| 773 |
+
"I32": np.dtype("<i4"),
|
| 774 |
+
"I64": np.dtype("<i8"),
|
| 775 |
+
"F16": np.dtype("<f2"),
|
| 776 |
+
"F32": np.dtype("<f4"),
|
| 777 |
+
"BF16": np.dtype("<u2"),
|
| 778 |
+
}
|
| 779 |
+
|
| 780 |
+
|
| 781 |
+
class _SafeTensorMMap:
|
| 782 |
+
def __init__(self, path):
|
| 783 |
+
self.path = Path(path)
|
| 784 |
+
self._file = self.path.open("rb")
|
| 785 |
+
raw_header_length = self._file.read(8)
|
| 786 |
+
if len(raw_header_length) != 8:
|
| 787 |
+
self.close()
|
| 788 |
+
raise ValueError(f"Invalid safetensors header in {self.path}")
|
| 789 |
+
header_length = struct.unpack("<Q", raw_header_length)[0]
|
| 790 |
+
raw_header = self._file.read(header_length)
|
| 791 |
+
if len(raw_header) != header_length:
|
| 792 |
+
self.close()
|
| 793 |
+
raise ValueError(f"Truncated safetensors header in {self.path}")
|
| 794 |
+
self._header = json.loads(raw_header)
|
| 795 |
+
self._data_start = 8 + header_length
|
| 796 |
+
self._mapping = mmap.mmap(self._file.fileno(), length=0, access=mmap.ACCESS_READ)
|
| 797 |
+
try:
|
| 798 |
+
self._mapping.madvise(mmap.MADV_RANDOM)
|
| 799 |
+
except (AttributeError, OSError):
|
| 800 |
+
pass
|
| 801 |
+
|
| 802 |
+
def tensor_shape(self, key):
|
| 803 |
+
try:
|
| 804 |
+
return tuple(self._header[key]["shape"])
|
| 805 |
+
except KeyError as exc:
|
| 806 |
+
raise KeyError(f"Tensor {key!r} is missing from {self.path}") from exc
|
| 807 |
+
|
| 808 |
+
def rows(self, key, row_indices):
|
| 809 |
+
try:
|
| 810 |
+
entry = self._header[key]
|
| 811 |
+
except KeyError as exc:
|
| 812 |
+
raise KeyError(f"Tensor {key!r} is missing from {self.path}") from exc
|
| 813 |
+
dtype_name = entry["dtype"]
|
| 814 |
+
try:
|
| 815 |
+
dtype = _SAFETENSORS_NUMPY_DTYPES[dtype_name]
|
| 816 |
+
except KeyError as exc:
|
| 817 |
+
raise TypeError(f"Unsupported safetensors dtype {dtype_name!r} for {key}") from exc
|
| 818 |
+
shape = tuple(entry["shape"])
|
| 819 |
+
if len(shape) != 2:
|
| 820 |
+
raise ValueError(f"Sparse PLE tensor {key!r} must be two-dimensional")
|
| 821 |
+
start, end = entry["data_offsets"]
|
| 822 |
+
if end - start != math.prod(shape) * dtype.itemsize:
|
| 823 |
+
raise ValueError(f"Invalid byte range for safetensors tensor {key!r}")
|
| 824 |
+
view = np.ndarray(
|
| 825 |
+
shape,
|
| 826 |
+
dtype=dtype,
|
| 827 |
+
buffer=self._mapping,
|
| 828 |
+
offset=self._data_start + start,
|
| 829 |
+
)
|
| 830 |
+
copied = np.array(view[np.asarray(row_indices, dtype=np.intp)], copy=True)
|
| 831 |
+
if dtype_name == "BF16":
|
| 832 |
+
copied = (copied.astype(np.uint32) << np.uint32(16)).view(np.float32)
|
| 833 |
+
return copied, dtype_name
|
| 834 |
+
|
| 835 |
+
def close(self):
|
| 836 |
+
mapping = getattr(self, "_mapping", None)
|
| 837 |
+
if mapping is not None:
|
| 838 |
+
mapping.close()
|
| 839 |
+
self._mapping = None
|
| 840 |
+
file_object = getattr(self, "_file", None)
|
| 841 |
+
if file_object is not None:
|
| 842 |
+
file_object.close()
|
| 843 |
+
self._file = None
|
| 844 |
+
|
| 845 |
+
def __del__(self):
|
| 846 |
+
try:
|
| 847 |
+
self.close()
|
| 848 |
+
except Exception:
|
| 849 |
+
pass
|
| 850 |
+
|
| 851 |
+
|
| 852 |
+
class DiskBackedShardedEmbedding(nn.Module):
|
| 853 |
+
def __init__(self, model_path, prefix, num_embeddings, dims, shard_count):
|
| 854 |
+
super().__init__()
|
| 855 |
+
if num_embeddings % shard_count:
|
| 856 |
+
raise ValueError("the padded n-gram vocabulary must divide evenly into shards")
|
| 857 |
+
self.shard_size = num_embeddings // shard_count
|
| 858 |
+
self.dims = dims
|
| 859 |
+
self.shard_count = shard_count
|
| 860 |
+
self.last_touched_shards = ()
|
| 861 |
+
self.rows_read = 0
|
| 862 |
+
self._prefix = prefix
|
| 863 |
+
self._readers = {}
|
| 864 |
+
self._tensor_readers = {}
|
| 865 |
+
self._shard_quantization = []
|
| 866 |
+
|
| 867 |
+
model_path = Path(model_path)
|
| 868 |
+
index_path = model_path / "model.safetensors.index.json"
|
| 869 |
+
config_path = model_path / "config.json"
|
| 870 |
+
if not index_path.exists() or not config_path.exists():
|
| 871 |
+
raise FileNotFoundError("SSD-backed PLE requires config.json and a safetensors index")
|
| 872 |
+
weight_map = json.loads(index_path.read_text()).get("weight_map", {})
|
| 873 |
+
quantization = json.loads(config_path.read_text()).get("quantization") or {}
|
| 874 |
+
default = {
|
| 875 |
+
"bits": int(quantization.get("bits", 4)),
|
| 876 |
+
"group_size": int(quantization.get("group_size", 64)),
|
| 877 |
+
"mode": quantization.get("mode", "affine"),
|
| 878 |
+
}
|
| 879 |
+
for shard_index in range(shard_count):
|
| 880 |
+
module_key = f"{prefix}.shards.{shard_index}"
|
| 881 |
+
settings = dict(default)
|
| 882 |
+
settings.update(quantization.get(module_key) or {})
|
| 883 |
+
bits = int(settings["bits"])
|
| 884 |
+
group_size = int(settings["group_size"])
|
| 885 |
+
mode = settings["mode"]
|
| 886 |
+
if mode != "affine":
|
| 887 |
+
raise ValueError("SSD-backed PLE supports affine quantization")
|
| 888 |
+
if dims % group_size or (dims * bits) % 32:
|
| 889 |
+
raise ValueError(f"Invalid PLE quantization for {module_key}")
|
| 890 |
+
self._shard_quantization.append((group_size, bits, mode))
|
| 891 |
+
expected_shapes = {
|
| 892 |
+
"weight": (self.shard_size, dims * bits // 32),
|
| 893 |
+
"scales": (self.shard_size, dims // group_size),
|
| 894 |
+
"biases": (self.shard_size, dims // group_size),
|
| 895 |
+
}
|
| 896 |
+
for suffix, expected_shape in expected_shapes.items():
|
| 897 |
+
key = f"{module_key}.{suffix}"
|
| 898 |
+
try:
|
| 899 |
+
filename = weight_map[key]
|
| 900 |
+
except KeyError as exc:
|
| 901 |
+
raise KeyError(f"SSD-backed PLE tensor {key!r} is absent from the index") from exc
|
| 902 |
+
reader = self._readers.get(filename)
|
| 903 |
+
if reader is None:
|
| 904 |
+
reader = _SafeTensorMMap(model_path / filename)
|
| 905 |
+
self._readers[filename] = reader
|
| 906 |
+
if reader.tensor_shape(key) != expected_shape:
|
| 907 |
+
raise ValueError(
|
| 908 |
+
f"Unexpected shape for {key}: {reader.tensor_shape(key)} != {expected_shape}"
|
| 909 |
+
)
|
| 910 |
+
self._tensor_readers[key] = reader
|
| 911 |
+
|
| 912 |
+
def _read_rows(self, key, row_indices):
|
| 913 |
+
array, dtype_name = self._tensor_readers[key].rows(key, row_indices)
|
| 914 |
+
self.rows_read += len(row_indices)
|
| 915 |
+
result = mx.array(array)
|
| 916 |
+
return result.astype(mx.bfloat16) if dtype_name == "BF16" else result
|
| 917 |
+
|
| 918 |
+
def __call__(self, ids):
|
| 919 |
+
shape = ids.shape
|
| 920 |
+
flat_ids = ids.reshape(-1).astype(mx.int64)
|
| 921 |
+
mx.eval(flat_ids)
|
| 922 |
+
host_ids = [int(value) for value in flat_ids.tolist()]
|
| 923 |
+
if any(value < 0 or value >= self.shard_size * self.shard_count for value in host_ids):
|
| 924 |
+
raise IndexError("n-gram embedding id is outside the padded vocabulary")
|
| 925 |
+
touched = tuple(sorted({value // self.shard_size for value in host_ids}))
|
| 926 |
+
self.last_touched_shards = touched
|
| 927 |
+
self.rows_read = 0
|
| 928 |
+
output = None
|
| 929 |
+
for shard_index in touched:
|
| 930 |
+
positions_list = [
|
| 931 |
+
index for index, value in enumerate(host_ids) if value // self.shard_size == shard_index
|
| 932 |
+
]
|
| 933 |
+
local_ids = [host_ids[index] % self.shard_size for index in positions_list]
|
| 934 |
+
base = f"{self._prefix}.shards.{shard_index}"
|
| 935 |
+
weight = self._read_rows(f"{base}.weight", local_ids)
|
| 936 |
+
scales = self._read_rows(f"{base}.scales", local_ids)
|
| 937 |
+
biases = self._read_rows(f"{base}.biases", local_ids)
|
| 938 |
+
group_size, bits, mode = self._shard_quantization[shard_index]
|
| 939 |
+
values = mx.dequantize(
|
| 940 |
+
weight,
|
| 941 |
+
scales=scales,
|
| 942 |
+
biases=biases,
|
| 943 |
+
group_size=group_size,
|
| 944 |
+
bits=bits,
|
| 945 |
+
mode=mode,
|
| 946 |
+
)
|
| 947 |
+
if output is None:
|
| 948 |
+
output = mx.zeros((len(host_ids), self.dims), dtype=values.dtype)
|
| 949 |
+
output[mx.array(positions_list, dtype=mx.int32)] = values
|
| 950 |
+
if output is None:
|
| 951 |
+
output = mx.zeros((0, self.dims), dtype=mx.bfloat16)
|
| 952 |
+
mx.eval(output)
|
| 953 |
+
return output.reshape(*shape, self.dims)
|
| 954 |
+
|
| 955 |
+
|
| 956 |
+
class Qwen4PLELayer(nn.Module):
|
| 957 |
+
def __init__(self, args: ModelArgs, ple_index: int, model_layer_index: int):
|
| 958 |
+
super().__init__()
|
| 959 |
+
total = args.hc_count * args.hidden_size
|
| 960 |
+
self.hc_count = args.hc_count
|
| 961 |
+
self.hidden_size = args.hidden_size
|
| 962 |
+
self.ple_embedding = Qwen4NGramEmbedding(args, ple_index, model_layer_index)
|
| 963 |
+
self.key_proj = nn.Linear(args.ple_embed_dim, total, bias=False)
|
| 964 |
+
self.value_proj = nn.Linear(args.ple_embed_dim, args.hidden_size, bias=False)
|
| 965 |
+
self.norm_key = Qwen4RMSNorm(total, args.rms_norm_eps, args.hidden_size)
|
| 966 |
+
self.norm_query = Qwen4RMSNorm(total, args.rms_norm_eps, args.hidden_size)
|
| 967 |
+
self.norm_conv = Qwen4RMSNorm(total, args.rms_norm_eps, args.hidden_size)
|
| 968 |
+
self.state_len = (args.ple_conv_kernel_size - 1) * args.ngram_size
|
| 969 |
+
self.conv1d = nn.Conv1d(
|
| 970 |
+
total,
|
| 971 |
+
total,
|
| 972 |
+
args.ple_conv_kernel_size,
|
| 973 |
+
dilation=args.ngram_size,
|
| 974 |
+
groups=total,
|
| 975 |
+
bias=False,
|
| 976 |
+
)
|
| 977 |
+
|
| 978 |
+
def __call__(self, x, input_ids, cache=None, mask=None):
|
| 979 |
+
embeddings = self.ple_embedding(input_ids, cache)
|
| 980 |
+
key = self.norm_key(self.key_proj(embeddings)).reshape(*x.shape[:-1], self.hc_count, self.hidden_size)
|
| 981 |
+
value = self.value_proj(embeddings)
|
| 982 |
+
query = self.norm_query(x).reshape(*x.shape[:-1], self.hc_count, self.hidden_size)
|
| 983 |
+
gate = mx.sum(key * query, axis=-1, keepdims=True) / math.sqrt(self.hidden_size)
|
| 984 |
+
gate = mx.sign(gate) * mx.sqrt(mx.maximum(mx.abs(gate), 1e-6))
|
| 985 |
+
gated = (mx.sigmoid(gate) * value[..., None, :]).reshape(*x.shape)
|
| 986 |
+
normalized = self.norm_conv(gated)
|
| 987 |
+
if mask is not None:
|
| 988 |
+
gated = mx.where(mask[..., None], gated, 0)
|
| 989 |
+
normalized = mx.where(mask[..., None], normalized, 0)
|
| 990 |
+
if cache is not None and cache[2] is not None:
|
| 991 |
+
state = cache[2]
|
| 992 |
+
else:
|
| 993 |
+
state = mx.zeros((x.shape[0], self.state_len, x.shape[-1]), dtype=x.dtype)
|
| 994 |
+
conv_input = mx.concatenate([state, normalized], axis=1)
|
| 995 |
+
if cache is not None:
|
| 996 |
+
cache[2] = mx.contiguous(conv_input[:, -self.state_len :, :])
|
| 997 |
+
return gated + nn.silu(self.conv1d(conv_input))
|
| 998 |
+
|
| 999 |
+
|
| 1000 |
+
class Qwen4DecoderLayer(nn.Module):
|
| 1001 |
+
def __init__(self, args: ModelArgs, index: int):
|
| 1002 |
+
super().__init__()
|
| 1003 |
+
self.is_linear = args.layer_types[index] == "linear_attention"
|
| 1004 |
+
if self.is_linear:
|
| 1005 |
+
self.linear_attn = Qwen4GatedDeltaNet(args)
|
| 1006 |
+
else:
|
| 1007 |
+
self.self_attn = Qwen4Attention(args)
|
| 1008 |
+
self.mlp = Qwen4SparseMoeBlock(args)
|
| 1009 |
+
one_indexed = index + 1
|
| 1010 |
+
self.ple = Qwen4PLELayer(args, args.ple_layer_ids.index(one_indexed), index) if one_indexed in args.ple_layer_ids else None
|
| 1011 |
+
self.attn_hyper_connection = Qwen4GatedResidual(args)
|
| 1012 |
+
self.mlp_hyper_connection = Qwen4GatedResidual(args)
|
| 1013 |
+
|
| 1014 |
+
def __call__(self, x, input_ids, mask=None, cache=None, n_confirmed=0):
|
| 1015 |
+
if self.ple is not None:
|
| 1016 |
+
x = x + self.ple(x, input_ids, cache, mask)
|
| 1017 |
+
mixed, residual, injection = self.attn_hyper_connection(x)
|
| 1018 |
+
output = (
|
| 1019 |
+
self.linear_attn(mixed, mask, cache, n_confirmed=n_confirmed)
|
| 1020 |
+
if self.is_linear
|
| 1021 |
+
else self.self_attn(mixed, cache)
|
| 1022 |
+
)
|
| 1023 |
+
x = residual + (output[..., None, :] * injection[..., None]).reshape(*residual.shape)
|
| 1024 |
+
mixed, residual, injection = self.mlp_hyper_connection(x)
|
| 1025 |
+
output = self.mlp(mixed)
|
| 1026 |
+
return residual + (output[..., None, :] * injection[..., None]).reshape(*residual.shape)
|
| 1027 |
+
|
| 1028 |
+
|
| 1029 |
+
class Qwen4MTPModule(nn.Module):
|
| 1030 |
+
def __init__(self, args: ModelArgs):
|
| 1031 |
+
super().__init__()
|
| 1032 |
+
self.hidden_size = args.hidden_size
|
| 1033 |
+
self.hc_count = args.hc_count
|
| 1034 |
+
total = self.hc_count * self.hidden_size
|
| 1035 |
+
self.pre_fc_norm_embedding = Qwen4RMSNorm(
|
| 1036 |
+
self.hidden_size,
|
| 1037 |
+
args.rms_norm_eps,
|
| 1038 |
+
)
|
| 1039 |
+
self.pre_fc_norm_hidden = Qwen4RMSNorm(total, args.rms_norm_eps)
|
| 1040 |
+
self.fc_embedding = nn.Linear(self.hidden_size, self.hidden_size, bias=False)
|
| 1041 |
+
self.fc_hidden = nn.Linear(self.hidden_size, self.hidden_size, bias=False)
|
| 1042 |
+
mtp_args = copy(args)
|
| 1043 |
+
mtp_args.num_hidden_layers = 1
|
| 1044 |
+
mtp_args.layer_types = ["full_attention"]
|
| 1045 |
+
mtp_args.ple_layer_ids = []
|
| 1046 |
+
self.layers = [Qwen4DecoderLayer(mtp_args, 0)]
|
| 1047 |
+
self.hyper_connection_mixer = Qwen4GatedResidual(mtp_args, combine=False)
|
| 1048 |
+
|
| 1049 |
+
def fuse_inputs(self, input_embeds, hidden_states):
|
| 1050 |
+
input_embeds = self.fc_embedding(
|
| 1051 |
+
self.pre_fc_norm_embedding(input_embeds)
|
| 1052 |
+
)
|
| 1053 |
+
original_shape = hidden_states.shape
|
| 1054 |
+
streams = self.pre_fc_norm_hidden(hidden_states).reshape(
|
| 1055 |
+
*hidden_states.shape[:-1],
|
| 1056 |
+
self.hc_count,
|
| 1057 |
+
self.hidden_size,
|
| 1058 |
+
)
|
| 1059 |
+
streams = self.fc_hidden(streams)
|
| 1060 |
+
return (streams + input_embeds[..., None, :]).reshape(original_shape)
|
| 1061 |
+
|
| 1062 |
+
def __call__(self, hidden_states, next_token_ids, embed_tokens, cache=None):
|
| 1063 |
+
hidden_states = self.fuse_inputs(
|
| 1064 |
+
embed_tokens(next_token_ids),
|
| 1065 |
+
hidden_states,
|
| 1066 |
+
)
|
| 1067 |
+
if cache is None:
|
| 1068 |
+
cache = [None] * len(self.layers)
|
| 1069 |
+
for layer, layer_cache in zip(self.layers, cache):
|
| 1070 |
+
hidden_states = layer(
|
| 1071 |
+
hidden_states,
|
| 1072 |
+
next_token_ids,
|
| 1073 |
+
cache=layer_cache,
|
| 1074 |
+
)
|
| 1075 |
+
return self.hyper_connection_mixer(hidden_states), hidden_states
|
| 1076 |
+
|
| 1077 |
+
|
| 1078 |
+
class Qwen4TextModel(nn.Module):
|
| 1079 |
+
def __init__(self, args: ModelArgs):
|
| 1080 |
+
super().__init__()
|
| 1081 |
+
self.args = args
|
| 1082 |
+
self.embed_tokens = nn.Embedding(args.vocab_size, args.hidden_size)
|
| 1083 |
+
self.layers = [Qwen4DecoderLayer(args, index) for index in range(args.num_hidden_layers)]
|
| 1084 |
+
self.hyper_connection_mixer = Qwen4GatedResidual(args, combine=False)
|
| 1085 |
+
|
| 1086 |
+
def __call__(self, inputs, cache=None, return_hidden=False, n_confirmed=0):
|
| 1087 |
+
hidden = self.embed_tokens(inputs)
|
| 1088 |
+
hidden = mx.tile(hidden, (1, 1, self.args.hc_count))
|
| 1089 |
+
if cache is None:
|
| 1090 |
+
cache = [None] * len(self.layers)
|
| 1091 |
+
linear_index = next((i for i, layer in enumerate(self.layers) if layer.is_linear), None)
|
| 1092 |
+
mask = create_ssm_mask(hidden, cache[linear_index]) if linear_index is not None else None
|
| 1093 |
+
for layer, layer_cache in zip(self.layers, cache):
|
| 1094 |
+
hidden = layer(
|
| 1095 |
+
hidden,
|
| 1096 |
+
inputs,
|
| 1097 |
+
mask,
|
| 1098 |
+
layer_cache,
|
| 1099 |
+
n_confirmed=n_confirmed,
|
| 1100 |
+
)
|
| 1101 |
+
output = self.hyper_connection_mixer(hidden)
|
| 1102 |
+
if return_hidden:
|
| 1103 |
+
return output, hidden
|
| 1104 |
+
return output
|
| 1105 |
+
|
| 1106 |
+
|
| 1107 |
+
def _decode_block_fp8(weight, scale, block=128):
|
| 1108 |
+
rows, columns = weight.shape
|
| 1109 |
+
grid_rows, grid_columns = scale.shape
|
| 1110 |
+
padded_rows, padded_columns = grid_rows * block, grid_columns * block
|
| 1111 |
+
decoded = mx.from_fp8(weight, dtype=mx.float32)
|
| 1112 |
+
decoded = mx.pad(decoded, ((0, padded_rows - rows), (0, padded_columns - columns)))
|
| 1113 |
+
decoded = decoded.reshape(grid_rows, block, grid_columns, block)
|
| 1114 |
+
decoded = decoded * scale.astype(mx.float32)[:, None, :, None]
|
| 1115 |
+
return decoded.reshape(padded_rows, padded_columns)[:rows, :columns].astype(mx.bfloat16)
|
| 1116 |
+
|
| 1117 |
+
|
| 1118 |
+
def register_oq_virtual_tensors(index, config):
|
| 1119 |
+
if config.get("model_type") != "qwen4_exp":
|
| 1120 |
+
return 0
|
| 1121 |
+
text_config = config.get("text_config", config)
|
| 1122 |
+
registrations = 0
|
| 1123 |
+
shard_count = int(text_config.get("split_ngram_parts", 0))
|
| 1124 |
+
for one_indexed_layer in text_config.get("ple_layer_ids", []):
|
| 1125 |
+
prefix = (
|
| 1126 |
+
f"model.language_model.layers.{one_indexed_layer - 1}.ple."
|
| 1127 |
+
"ple_embedding.ngram_embedding"
|
| 1128 |
+
)
|
| 1129 |
+
scale_key = prefix + ".weight_scale"
|
| 1130 |
+
if index.source_shape(scale_key) is None:
|
| 1131 |
+
continue
|
| 1132 |
+
for shard_index in range(shard_count):
|
| 1133 |
+
weight_key = f"{prefix}.shard_{shard_index}.weight"
|
| 1134 |
+
shape = index.source_shape(weight_key)
|
| 1135 |
+
if shape is None:
|
| 1136 |
+
raise ValueError(f"Missing Qwen4 PLE shard: {weight_key}")
|
| 1137 |
+
|
| 1138 |
+
def materialize(weight_key=weight_key, scale_key=scale_key):
|
| 1139 |
+
weight = index.load_source(weight_key)
|
| 1140 |
+
scale = index.load_source(scale_key)
|
| 1141 |
+
value = mx.from_fp8(weight, dtype=mx.bfloat16) * scale
|
| 1142 |
+
mx.eval(value)
|
| 1143 |
+
return value
|
| 1144 |
+
|
| 1145 |
+
index.register_virtual(
|
| 1146 |
+
weight_key,
|
| 1147 |
+
shape,
|
| 1148 |
+
"BF16",
|
| 1149 |
+
materialize,
|
| 1150 |
+
hides=(weight_key, scale_key),
|
| 1151 |
+
)
|
| 1152 |
+
registrations += 1
|
| 1153 |
+
return registrations
|
| 1154 |
+
|
| 1155 |
+
|
| 1156 |
+
class Model(nn.Module):
|
| 1157 |
+
def __init__(self, args: ModelArgs):
|
| 1158 |
+
super().__init__()
|
| 1159 |
+
self.args = args
|
| 1160 |
+
self.model_type = args.model_type
|
| 1161 |
+
self.model = Qwen4TextModel(args)
|
| 1162 |
+
if not args.tie_word_embeddings:
|
| 1163 |
+
self.lm_head = nn.Linear(args.hidden_size, args.vocab_size, bias=False)
|
| 1164 |
+
mtp_active = False
|
| 1165 |
+
if args.mtp_num_hidden_layers:
|
| 1166 |
+
try:
|
| 1167 |
+
from omlx.patches.mlx_lm_mtp import is_mtp_active
|
| 1168 |
+
|
| 1169 |
+
mtp_active = is_mtp_active()
|
| 1170 |
+
except ImportError:
|
| 1171 |
+
mtp_active = False
|
| 1172 |
+
self._omlx_mtp_decode_enabled = bool(mtp_active)
|
| 1173 |
+
if mtp_active:
|
| 1174 |
+
if args.mtp_num_hidden_layers != 1:
|
| 1175 |
+
raise ValueError("Qwen4 requires exactly one MTP decoder layer")
|
| 1176 |
+
self.mtp = Qwen4MTPModule(args)
|
| 1177 |
+
self._omlx_mtp_chain = True
|
| 1178 |
+
self._omlx_mtp_depth = 1
|
| 1179 |
+
self._omlx_mtp_head_prenorm = True
|
| 1180 |
+
|
| 1181 |
+
def __call__(self, inputs, cache=None, return_hidden=False, n_confirmed=0):
|
| 1182 |
+
need_hidden = return_hidden or hasattr(self, "mtp")
|
| 1183 |
+
result = self.model(
|
| 1184 |
+
inputs,
|
| 1185 |
+
cache,
|
| 1186 |
+
return_hidden=need_hidden,
|
| 1187 |
+
n_confirmed=n_confirmed,
|
| 1188 |
+
)
|
| 1189 |
+
if need_hidden:
|
| 1190 |
+
output, hidden = result
|
| 1191 |
+
else:
|
| 1192 |
+
output = result
|
| 1193 |
+
if self.args.tie_word_embeddings:
|
| 1194 |
+
logits = self.model.embed_tokens.as_linear(output)
|
| 1195 |
+
else:
|
| 1196 |
+
logits = self.lm_head(output)
|
| 1197 |
+
if (
|
| 1198 |
+
hasattr(self, "mtp")
|
| 1199 |
+
and not return_hidden
|
| 1200 |
+
and not n_confirmed
|
| 1201 |
+
):
|
| 1202 |
+
try:
|
| 1203 |
+
from omlx.patches.mlx_lm_mtp import prompt_priming
|
| 1204 |
+
|
| 1205 |
+
prompt_priming.maybe_capture(self, inputs, hidden, cache)
|
| 1206 |
+
except Exception:
|
| 1207 |
+
logger.debug("Qwen4 MTP prompt priming failed", exc_info=True)
|
| 1208 |
+
if return_hidden:
|
| 1209 |
+
return logits, hidden
|
| 1210 |
+
return logits
|
| 1211 |
+
|
| 1212 |
+
def mtp_forward(
|
| 1213 |
+
self,
|
| 1214 |
+
hidden_states,
|
| 1215 |
+
next_token_ids,
|
| 1216 |
+
mtp_cache,
|
| 1217 |
+
return_hidden=False,
|
| 1218 |
+
logits_keep=0,
|
| 1219 |
+
):
|
| 1220 |
+
if not hasattr(self, "mtp"):
|
| 1221 |
+
raise RuntimeError("Qwen4 MTP forward called without an attached head")
|
| 1222 |
+
output, hidden = self.mtp(
|
| 1223 |
+
hidden_states,
|
| 1224 |
+
next_token_ids,
|
| 1225 |
+
self.model.embed_tokens,
|
| 1226 |
+
mtp_cache,
|
| 1227 |
+
)
|
| 1228 |
+
if logits_keep and output.shape[1] > logits_keep:
|
| 1229 |
+
output = output[:, -logits_keep:, :]
|
| 1230 |
+
if self.args.tie_word_embeddings:
|
| 1231 |
+
logits = self.model.embed_tokens.as_linear(output)
|
| 1232 |
+
else:
|
| 1233 |
+
logits = self.lm_head(output)
|
| 1234 |
+
if return_hidden:
|
| 1235 |
+
return logits, hidden
|
| 1236 |
+
return logits
|
| 1237 |
+
|
| 1238 |
+
def make_mtp_cache(self):
|
| 1239 |
+
if not hasattr(self, "mtp"):
|
| 1240 |
+
return []
|
| 1241 |
+
return [QSAKVCache() for _ in self.mtp.layers]
|
| 1242 |
+
|
| 1243 |
+
def mtp_partial_rollback(self, cache, accepted, num_drafts):
|
| 1244 |
+
if len(cache) != len(self.layers):
|
| 1245 |
+
return False
|
| 1246 |
+
trim = int(num_drafts) - int(accepted)
|
| 1247 |
+
if trim <= 0:
|
| 1248 |
+
return True
|
| 1249 |
+
keep = 1 + int(accepted)
|
| 1250 |
+
for layer, layer_cache in zip(self.layers, cache):
|
| 1251 |
+
if layer.is_linear:
|
| 1252 |
+
if getattr(layer_cache, "rollback_state", None) is None:
|
| 1253 |
+
return False
|
| 1254 |
+
if getattr(layer_cache, "_mtp_draft_stash", None) is None:
|
| 1255 |
+
return False
|
| 1256 |
+
elif not layer_cache.is_trimmable():
|
| 1257 |
+
return False
|
| 1258 |
+
for layer, layer_cache in zip(self.layers, cache):
|
| 1259 |
+
if layer.is_linear:
|
| 1260 |
+
conv_state, state = layer_cache.rollback_state
|
| 1261 |
+
mixed, a, b, mask = layer_cache._mtp_draft_stash
|
| 1262 |
+
if mask is not None:
|
| 1263 |
+
mask = mask[:, :keep]
|
| 1264 |
+
_, next_conv_state, next_state = layer.linear_attn._process_chunk(
|
| 1265 |
+
mixed[:, :keep],
|
| 1266 |
+
a[:, :keep],
|
| 1267 |
+
b[:, :keep],
|
| 1268 |
+
conv_state,
|
| 1269 |
+
state,
|
| 1270 |
+
mask,
|
| 1271 |
+
)
|
| 1272 |
+
layer_cache[0] = next_conv_state
|
| 1273 |
+
layer_cache[1] = next_state
|
| 1274 |
+
layer_cache.rollback_state = None
|
| 1275 |
+
layer_cache._mtp_draft_stash = None
|
| 1276 |
+
else:
|
| 1277 |
+
layer_cache.trim(trim)
|
| 1278 |
+
return True
|
| 1279 |
+
|
| 1280 |
+
@property
|
| 1281 |
+
def layers(self):
|
| 1282 |
+
return self.model.layers
|
| 1283 |
+
|
| 1284 |
+
def make_cache(self):
|
| 1285 |
+
return [ArraysCache(size=4) if layer.is_linear else QSAKVCache() for layer in self.layers]
|
| 1286 |
+
|
| 1287 |
+
def sanitize(self, weights):
|
| 1288 |
+
cleaned = {}
|
| 1289 |
+
for key, value in weights.items():
|
| 1290 |
+
if key.startswith("mtp.") and not hasattr(self, "mtp"):
|
| 1291 |
+
continue
|
| 1292 |
+
if key.startswith("model.visual."):
|
| 1293 |
+
continue
|
| 1294 |
+
if key.startswith("model.language_model."):
|
| 1295 |
+
key = "model." + key[len("model.language_model.") :]
|
| 1296 |
+
cleaned[key] = value
|
| 1297 |
+
weights = cleaned
|
| 1298 |
+
if self.args.tie_word_embeddings:
|
| 1299 |
+
weights.pop("lm_head.weight", None)
|
| 1300 |
+
expert_prefixes = [
|
| 1301 |
+
f"model.layers.{layer_index}.mlp"
|
| 1302 |
+
for layer_index in range(self.args.num_hidden_layers)
|
| 1303 |
+
]
|
| 1304 |
+
if hasattr(self, "mtp"):
|
| 1305 |
+
expert_prefixes.extend(
|
| 1306 |
+
f"mtp.layers.{layer_index}.mlp"
|
| 1307 |
+
for layer_index in range(self.args.mtp_num_hidden_layers)
|
| 1308 |
+
)
|
| 1309 |
+
for prefix in expert_prefixes:
|
| 1310 |
+
if f"{prefix}.experts.0.up_proj.weight" not in weights:
|
| 1311 |
+
continue
|
| 1312 |
+
for projection in ("up_proj", "gate_proj", "down_proj"):
|
| 1313 |
+
values = []
|
| 1314 |
+
for expert in range(self.args.num_experts):
|
| 1315 |
+
key = f"{prefix}.experts.{expert}.{projection}.weight"
|
| 1316 |
+
scale_key = key + "_scale_inv"
|
| 1317 |
+
value = weights.pop(key)
|
| 1318 |
+
if scale_key in weights:
|
| 1319 |
+
value = _decode_block_fp8(value, weights.pop(scale_key))
|
| 1320 |
+
values.append(value)
|
| 1321 |
+
weights[f"{prefix}.switch_mlp.{projection}.weight"] = mx.stack(values)
|
| 1322 |
+
for layer_index in range(self.args.num_hidden_layers):
|
| 1323 |
+
base = f"model.layers.{layer_index}.ple.ple_embedding.ngram_embedding"
|
| 1324 |
+
layer = self.model.layers[layer_index]
|
| 1325 |
+
disk_backed = (
|
| 1326 |
+
layer.ple is not None
|
| 1327 |
+
and isinstance(
|
| 1328 |
+
layer.ple.ple_embedding.ngram_embedding,
|
| 1329 |
+
DiskBackedShardedEmbedding,
|
| 1330 |
+
)
|
| 1331 |
+
)
|
| 1332 |
+
if disk_backed:
|
| 1333 |
+
for key in list(weights):
|
| 1334 |
+
if key.startswith(base + ".shards."):
|
| 1335 |
+
weights.pop(key)
|
| 1336 |
+
shard_keys = [key for key in weights if key.startswith(base + ".shard_") and key.endswith(".weight")]
|
| 1337 |
+
if not shard_keys:
|
| 1338 |
+
continue
|
| 1339 |
+
shard_keys.sort(key=lambda key: int(key.split(".shard_")[1].split(".")[0]))
|
| 1340 |
+
scale = weights.pop(base + ".weight_scale", None)
|
| 1341 |
+
for shard_index, key in enumerate(shard_keys):
|
| 1342 |
+
value = weights.pop(key)
|
| 1343 |
+
if scale is not None:
|
| 1344 |
+
value = mx.from_fp8(value, dtype=mx.bfloat16) * scale
|
| 1345 |
+
weights[f"{base}.shards.{shard_index}.weight"] = value
|
| 1346 |
+
for key in list(weights):
|
| 1347 |
+
value = weights[key]
|
| 1348 |
+
if key.endswith("conv1d.weight") and value.ndim == 3 and value.shape[-1] != 1:
|
| 1349 |
+
weights[key] = value.moveaxis(2, 1)
|
| 1350 |
+
return weights
|
| 1351 |
+
|
| 1352 |
+
@property
|
| 1353 |
+
def quant_predicate(self):
|
| 1354 |
+
def predicate(path, module):
|
| 1355 |
+
if "ple_embedding.ngram_embedding.shards." in path:
|
| 1356 |
+
return {"group_size": 32, "bits": 4}
|
| 1357 |
+
if path.endswith("mlp.gate") or path.endswith("shared_expert_gate"):
|
| 1358 |
+
return {"group_size": 64, "bits": 8}
|
| 1359 |
+
return hasattr(module, "to_quantized")
|
| 1360 |
+
|
| 1361 |
+
return predicate
|
omlx_support/qwen4_mtp_integration.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
def register_qwen4_mtp_integration():
|
| 2 |
+
try:
|
| 3 |
+
from omlx.utils import model_loading
|
| 4 |
+
except ImportError:
|
| 5 |
+
return False
|
| 6 |
+
if getattr(model_loading, "_qwen4_mtp_compatible_installed", False):
|
| 7 |
+
return True
|
| 8 |
+
|
| 9 |
+
original = model_loading._is_mtp_compatible
|
| 10 |
+
|
| 11 |
+
def compatible(config, model_type):
|
| 12 |
+
if model_type == "qwen4_exp":
|
| 13 |
+
return model_loading._has_mtp_heads(config)
|
| 14 |
+
return original(config, model_type)
|
| 15 |
+
|
| 16 |
+
model_loading._is_mtp_compatible = compatible
|
| 17 |
+
model_loading._qwen4_mtp_compatible_installed = True
|
| 18 |
+
return True
|
omlx_support/serve
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/zsh
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
support_root=${0:A:h}
|
| 5 |
+
model_root=${support_root:h}
|
| 6 |
+
models_root=${model_root:h}
|
| 7 |
+
base_path=${OMLX_BASE_PATH:-$model_root/.omlx}
|
| 8 |
+
cache_dir=${OMLX_CACHE_DIR:-$base_path/cache}
|
| 9 |
+
api_key=${OMLX_API_KEY:-omlx}
|
| 10 |
+
port=${OMLX_PORT:-8766}
|
| 11 |
+
|
| 12 |
+
mkdir -p "$cache_dir"
|
| 13 |
+
if [[ ! -f "$base_path/model_settings.json" ]]; then
|
| 14 |
+
cp "$support_root/model_settings.json" "$base_path/model_settings.json"
|
| 15 |
+
fi
|
| 16 |
+
export OMLX_QWEN4_PLE_MODE=mmap
|
| 17 |
+
export OMLX_QWEN4_PLE_MODEL_PATH="$model_root"
|
| 18 |
+
export OMLX_MTP_PROMPT_PRIMING=1
|
| 19 |
+
export OMLX_MTP_PRIME_WINDOW=8192
|
| 20 |
+
|
| 21 |
+
exec /bin/zsh "$support_root/with-omlx-python" -m omlx.cli serve \
|
| 22 |
+
--model-dir "$models_root" \
|
| 23 |
+
--host 127.0.0.1 \
|
| 24 |
+
--port "$port" \
|
| 25 |
+
--max-concurrent-requests 1 \
|
| 26 |
+
--memory-guard balanced \
|
| 27 |
+
--paged-ssd-cache-dir "$cache_dir" \
|
| 28 |
+
--paged-ssd-cache-max-size 128GB \
|
| 29 |
+
--hot-cache-max-size 0 \
|
| 30 |
+
--initial-cache-blocks 1 \
|
| 31 |
+
--no-hf-cache \
|
| 32 |
+
--base-path "$base_path" \
|
| 33 |
+
--api-key "$api_key"
|
omlx_support/sitecustomize.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from pathlib import Path
|
| 2 |
+
|
| 3 |
+
import mlx_lm.models
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
model_path = str(Path(__file__).resolve().parent)
|
| 7 |
+
if model_path not in mlx_lm.models.__path__:
|
| 8 |
+
mlx_lm.models.__path__.insert(0, model_path)
|
| 9 |
+
|
| 10 |
+
from qwen4_cache_integration import register_qwen4_cache_integration
|
| 11 |
+
from qwen4_mtp_integration import register_qwen4_mtp_integration
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
register_qwen4_cache_integration()
|
| 15 |
+
register_qwen4_mtp_integration()
|
omlx_support/with-omlx-python
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/zsh
|
| 2 |
+
set -euo pipefail
|
| 3 |
+
|
| 4 |
+
support_root=${0:A:h}
|
| 5 |
+
model_root=${support_root:h}
|
| 6 |
+
app_resources=${OMLX_APP_RESOURCES:-/Applications/oMLX.app/Contents/Resources}
|
| 7 |
+
python_root=$app_resources/Python
|
| 8 |
+
cpython_root=$python_root/cpython-3.11
|
| 9 |
+
mlx_site=$python_root/framework-mlx-base/lib/python3.11/site-packages
|
| 10 |
+
mlx_runtime=${OMLX_MLX_RUNTIME:-$model_root/.mlx-runtime}
|
| 11 |
+
|
| 12 |
+
if [[ ! -d "$mlx_runtime/mlx" ]]; then
|
| 13 |
+
print -u2 "MLX 0.32.1 is missing from $mlx_runtime"
|
| 14 |
+
print -u2 "Install it with: uv pip install --target $mlx_runtime mlx==0.32.1 mlx-metal==0.32.1"
|
| 15 |
+
exit 1
|
| 16 |
+
fi
|
| 17 |
+
|
| 18 |
+
export PYTHONHOME=$cpython_root
|
| 19 |
+
export PYTHONDONTWRITEBYTECODE=1
|
| 20 |
+
export PYTHONPATH="$support_root:$mlx_runtime:$app_resources:$mlx_site"
|
| 21 |
+
|
| 22 |
+
exec "$cpython_root/bin/python3" "$@"
|
oq_imatrix_report.json
ADDED
|
@@ -0,0 +1,870 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"enabled": true,
|
| 3 |
+
"cache_path": null,
|
| 4 |
+
"cache_reused": true,
|
| 5 |
+
"entry_count": 914,
|
| 6 |
+
"calib_dataset": "oqe_code_multilingual",
|
| 7 |
+
"collection": {
|
| 8 |
+
"dataset": "oqe_code_multilingual",
|
| 9 |
+
"requested_samples": 128,
|
| 10 |
+
"seq_length": 512,
|
| 11 |
+
"adaptive": true,
|
| 12 |
+
"adaptive_step_samples": 128,
|
| 13 |
+
"adaptive_max_samples": 1024,
|
| 14 |
+
"available_samples": 1024,
|
| 15 |
+
"micro_batch_size": 6,
|
| 16 |
+
"micro_batches": 176,
|
| 17 |
+
"batch_plan": {
|
| 18 |
+
"micro_batch_size": 6,
|
| 19 |
+
"estimated_sample_bytes": 52428800,
|
| 20 |
+
"capture_budget_bytes": 362029891,
|
| 21 |
+
"system_available_bytes": 103756529664,
|
| 22 |
+
"metal_available_bytes": 115443233112,
|
| 23 |
+
"live_available_bytes": 103756529664,
|
| 24 |
+
"model_bytes": 67553540501,
|
| 25 |
+
"remaining_available_bytes": 36202989163,
|
| 26 |
+
"fits_one_sample": true,
|
| 27 |
+
"hidden_size": 2560,
|
| 28 |
+
"num_experts": 512,
|
| 29 |
+
"top_k": 10,
|
| 30 |
+
"gemma4_state_bytes": 0,
|
| 31 |
+
"num_hidden_layers": 48,
|
| 32 |
+
"num_kv_shared_layers": 0,
|
| 33 |
+
"per_layer_input_size": 0
|
| 34 |
+
},
|
| 35 |
+
"processed_samples": 1024,
|
| 36 |
+
"installed_modules": 917,
|
| 37 |
+
"capture_module_classes": {
|
| 38 |
+
"Linear": 388,
|
| 39 |
+
"QuantizedLinear": 385,
|
| 40 |
+
"QuantizedSwitchLinear": 144
|
| 41 |
+
},
|
| 42 |
+
"switch_capture_modules": 144,
|
| 43 |
+
"requires_expert_counts": true,
|
| 44 |
+
"coverage_sufficient": false,
|
| 45 |
+
"collection_sufficient": false,
|
| 46 |
+
"coverage": {
|
| 47 |
+
"has_expert_counts": true,
|
| 48 |
+
"expert_modules": 144,
|
| 49 |
+
"total_experts": 73728,
|
| 50 |
+
"active_experts": 73665,
|
| 51 |
+
"zero_count_experts": 63,
|
| 52 |
+
"active_ratio": 0.9991455078125,
|
| 53 |
+
"min_count": 0,
|
| 54 |
+
"p05_count": 717.0,
|
| 55 |
+
"p10_count": 1432.0,
|
| 56 |
+
"median_count": 7353.0,
|
| 57 |
+
"max_count": 341355,
|
| 58 |
+
"min_required_count": 16,
|
| 59 |
+
"required_percentile": 5
|
| 60 |
+
},
|
| 61 |
+
"rounds": [
|
| 62 |
+
{
|
| 63 |
+
"processed_samples": 128,
|
| 64 |
+
"coverage_sufficient": false,
|
| 65 |
+
"collection_sufficient": false,
|
| 66 |
+
"coverage": {
|
| 67 |
+
"has_expert_counts": true,
|
| 68 |
+
"expert_modules": 144,
|
| 69 |
+
"total_experts": 73728,
|
| 70 |
+
"active_experts": 73530,
|
| 71 |
+
"zero_count_experts": 198,
|
| 72 |
+
"active_ratio": 0.997314453125,
|
| 73 |
+
"min_count": 0,
|
| 74 |
+
"p05_count": 71.0,
|
| 75 |
+
"p10_count": 158.0,
|
| 76 |
+
"median_count": 913.0,
|
| 77 |
+
"max_count": 41723,
|
| 78 |
+
"min_required_count": 16,
|
| 79 |
+
"required_percentile": 5
|
| 80 |
+
}
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"processed_samples": 256,
|
| 84 |
+
"coverage_sufficient": false,
|
| 85 |
+
"collection_sufficient": false,
|
| 86 |
+
"coverage": {
|
| 87 |
+
"has_expert_counts": true,
|
| 88 |
+
"expert_modules": 144,
|
| 89 |
+
"total_experts": 73728,
|
| 90 |
+
"active_experts": 73587,
|
| 91 |
+
"zero_count_experts": 141,
|
| 92 |
+
"active_ratio": 0.9980875651041666,
|
| 93 |
+
"min_count": 0,
|
| 94 |
+
"p05_count": 174.0,
|
| 95 |
+
"p10_count": 353.0,
|
| 96 |
+
"median_count": 1830.0,
|
| 97 |
+
"max_count": 83264,
|
| 98 |
+
"min_required_count": 16,
|
| 99 |
+
"required_percentile": 5
|
| 100 |
+
}
|
| 101 |
+
},
|
| 102 |
+
{
|
| 103 |
+
"processed_samples": 384,
|
| 104 |
+
"coverage_sufficient": false,
|
| 105 |
+
"collection_sufficient": false,
|
| 106 |
+
"coverage": {
|
| 107 |
+
"has_expert_counts": true,
|
| 108 |
+
"expert_modules": 144,
|
| 109 |
+
"total_experts": 73728,
|
| 110 |
+
"active_experts": 73629,
|
| 111 |
+
"zero_count_experts": 99,
|
| 112 |
+
"active_ratio": 0.9986572265625,
|
| 113 |
+
"min_count": 0,
|
| 114 |
+
"p05_count": 285.35000000000036,
|
| 115 |
+
"p10_count": 553.0,
|
| 116 |
+
"median_count": 2755.0,
|
| 117 |
+
"max_count": 124541,
|
| 118 |
+
"min_required_count": 16,
|
| 119 |
+
"required_percentile": 5
|
| 120 |
+
}
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"processed_samples": 512,
|
| 124 |
+
"coverage_sufficient": false,
|
| 125 |
+
"collection_sufficient": false,
|
| 126 |
+
"coverage": {
|
| 127 |
+
"has_expert_counts": true,
|
| 128 |
+
"expert_modules": 144,
|
| 129 |
+
"total_experts": 73728,
|
| 130 |
+
"active_experts": 73641,
|
| 131 |
+
"zero_count_experts": 87,
|
| 132 |
+
"active_ratio": 0.9988199869791666,
|
| 133 |
+
"min_count": 0,
|
| 134 |
+
"p05_count": 369.35000000000036,
|
| 135 |
+
"p10_count": 737.0,
|
| 136 |
+
"median_count": 3687.5,
|
| 137 |
+
"max_count": 168254,
|
| 138 |
+
"min_required_count": 16,
|
| 139 |
+
"required_percentile": 5
|
| 140 |
+
}
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"processed_samples": 640,
|
| 144 |
+
"coverage_sufficient": false,
|
| 145 |
+
"collection_sufficient": false,
|
| 146 |
+
"coverage": {
|
| 147 |
+
"has_expert_counts": true,
|
| 148 |
+
"expert_modules": 144,
|
| 149 |
+
"total_experts": 73728,
|
| 150 |
+
"active_experts": 73653,
|
| 151 |
+
"zero_count_experts": 75,
|
| 152 |
+
"active_ratio": 0.9989827473958334,
|
| 153 |
+
"min_count": 0,
|
| 154 |
+
"p05_count": 453.35000000000036,
|
| 155 |
+
"p10_count": 904.0,
|
| 156 |
+
"median_count": 4619.0,
|
| 157 |
+
"max_count": 213373,
|
| 158 |
+
"min_required_count": 16,
|
| 159 |
+
"required_percentile": 5
|
| 160 |
+
}
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"processed_samples": 768,
|
| 164 |
+
"coverage_sufficient": false,
|
| 165 |
+
"collection_sufficient": false,
|
| 166 |
+
"coverage": {
|
| 167 |
+
"has_expert_counts": true,
|
| 168 |
+
"expert_modules": 144,
|
| 169 |
+
"total_experts": 73728,
|
| 170 |
+
"active_experts": 73656,
|
| 171 |
+
"zero_count_experts": 72,
|
| 172 |
+
"active_ratio": 0.9990234375,
|
| 173 |
+
"min_count": 0,
|
| 174 |
+
"p05_count": 539.0,
|
| 175 |
+
"p10_count": 1076.0,
|
| 176 |
+
"median_count": 5501.5,
|
| 177 |
+
"max_count": 255296,
|
| 178 |
+
"min_required_count": 16,
|
| 179 |
+
"required_percentile": 5
|
| 180 |
+
}
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"processed_samples": 896,
|
| 184 |
+
"coverage_sufficient": false,
|
| 185 |
+
"collection_sufficient": false,
|
| 186 |
+
"coverage": {
|
| 187 |
+
"has_expert_counts": true,
|
| 188 |
+
"expert_modules": 144,
|
| 189 |
+
"total_experts": 73728,
|
| 190 |
+
"active_experts": 73659,
|
| 191 |
+
"zero_count_experts": 69,
|
| 192 |
+
"active_ratio": 0.9990641276041666,
|
| 193 |
+
"min_count": 0,
|
| 194 |
+
"p05_count": 628.0,
|
| 195 |
+
"p10_count": 1257.0,
|
| 196 |
+
"median_count": 6420.0,
|
| 197 |
+
"max_count": 298656,
|
| 198 |
+
"min_required_count": 16,
|
| 199 |
+
"required_percentile": 5
|
| 200 |
+
}
|
| 201 |
+
},
|
| 202 |
+
{
|
| 203 |
+
"processed_samples": 1024,
|
| 204 |
+
"coverage_sufficient": false,
|
| 205 |
+
"collection_sufficient": false,
|
| 206 |
+
"coverage": {
|
| 207 |
+
"has_expert_counts": true,
|
| 208 |
+
"expert_modules": 144,
|
| 209 |
+
"total_experts": 73728,
|
| 210 |
+
"active_experts": 73665,
|
| 211 |
+
"zero_count_experts": 63,
|
| 212 |
+
"active_ratio": 0.9991455078125,
|
| 213 |
+
"min_count": 0,
|
| 214 |
+
"p05_count": 717.0,
|
| 215 |
+
"p10_count": 1432.0,
|
| 216 |
+
"median_count": 7353.0,
|
| 217 |
+
"max_count": 341355,
|
| 218 |
+
"min_required_count": 16,
|
| 219 |
+
"required_percentile": 5
|
| 220 |
+
}
|
| 221 |
+
}
|
| 222 |
+
]
|
| 223 |
+
},
|
| 224 |
+
"expert_coverage": {
|
| 225 |
+
"has_expert_counts": true,
|
| 226 |
+
"expert_modules": 144,
|
| 227 |
+
"total_experts": 73728,
|
| 228 |
+
"active_experts": 73665,
|
| 229 |
+
"zero_count_experts": 63,
|
| 230 |
+
"active_ratio": 0.9991455078125,
|
| 231 |
+
"min_count": 0,
|
| 232 |
+
"p05_count": 717.0,
|
| 233 |
+
"p10_count": 1432.0,
|
| 234 |
+
"median_count": 7353.0,
|
| 235 |
+
"max_count": 341355,
|
| 236 |
+
"min_required_count": 16,
|
| 237 |
+
"required_percentile": 5
|
| 238 |
+
},
|
| 239 |
+
"applied": [
|
| 240 |
+
"model.layers.0.attn_hyper_connection.input_mix_weight_down",
|
| 241 |
+
"model.layers.0.linear_attn.in_proj_a",
|
| 242 |
+
"model.layers.0.linear_attn.in_proj_b",
|
| 243 |
+
"model.layers.0.linear_attn.in_proj_qkv",
|
| 244 |
+
"model.layers.0.linear_attn.in_proj_z",
|
| 245 |
+
"model.layers.0.linear_attn.out_proj",
|
| 246 |
+
"model.layers.0.mlp.shared_expert.down_proj",
|
| 247 |
+
"model.layers.0.mlp.shared_expert.gate_proj",
|
| 248 |
+
"model.layers.0.mlp.shared_expert.up_proj",
|
| 249 |
+
"model.layers.0.mlp.switch_mlp.down_proj",
|
| 250 |
+
"model.layers.0.mlp.switch_mlp.gate_proj",
|
| 251 |
+
"model.layers.0.mlp.switch_mlp.up_proj",
|
| 252 |
+
"model.layers.0.mlp_hyper_connection.input_mix_weight_down",
|
| 253 |
+
"model.layers.1.attn_hyper_connection.input_mix_weight_down",
|
| 254 |
+
"model.layers.1.linear_attn.in_proj_a",
|
| 255 |
+
"model.layers.1.linear_attn.in_proj_b",
|
| 256 |
+
"model.layers.1.linear_attn.in_proj_qkv",
|
| 257 |
+
"model.layers.1.linear_attn.in_proj_z",
|
| 258 |
+
"model.layers.1.linear_attn.out_proj",
|
| 259 |
+
"model.layers.1.mlp.shared_expert.down_proj",
|
| 260 |
+
"model.layers.1.mlp.shared_expert.gate_proj",
|
| 261 |
+
"model.layers.1.mlp.shared_expert.up_proj",
|
| 262 |
+
"model.layers.1.mlp.switch_mlp.down_proj",
|
| 263 |
+
"model.layers.1.mlp.switch_mlp.gate_proj",
|
| 264 |
+
"model.layers.1.mlp.switch_mlp.up_proj",
|
| 265 |
+
"model.layers.1.mlp_hyper_connection.input_mix_weight_down",
|
| 266 |
+
"model.layers.1.ple.key_proj",
|
| 267 |
+
"model.layers.1.ple.value_proj",
|
| 268 |
+
"model.layers.10.attn_hyper_connection.input_mix_weight_down",
|
| 269 |
+
"model.layers.10.linear_attn.in_proj_a",
|
| 270 |
+
"model.layers.10.linear_attn.in_proj_b",
|
| 271 |
+
"model.layers.10.linear_attn.in_proj_qkv",
|
| 272 |
+
"model.layers.10.linear_attn.in_proj_z",
|
| 273 |
+
"model.layers.10.linear_attn.out_proj",
|
| 274 |
+
"model.layers.10.mlp.shared_expert.down_proj",
|
| 275 |
+
"model.layers.10.mlp.shared_expert.gate_proj",
|
| 276 |
+
"model.layers.10.mlp.shared_expert.up_proj",
|
| 277 |
+
"model.layers.10.mlp.switch_mlp.down_proj",
|
| 278 |
+
"model.layers.10.mlp.switch_mlp.gate_proj",
|
| 279 |
+
"model.layers.10.mlp.switch_mlp.up_proj",
|
| 280 |
+
"model.layers.10.mlp_hyper_connection.input_mix_weight_down",
|
| 281 |
+
"model.layers.11.attn_hyper_connection.input_mix_weight_down",
|
| 282 |
+
"model.layers.11.mlp.shared_expert.down_proj",
|
| 283 |
+
"model.layers.11.mlp.shared_expert.gate_proj",
|
| 284 |
+
"model.layers.11.mlp.shared_expert.up_proj",
|
| 285 |
+
"model.layers.11.mlp.switch_mlp.down_proj",
|
| 286 |
+
"model.layers.11.mlp.switch_mlp.gate_proj",
|
| 287 |
+
"model.layers.11.mlp.switch_mlp.up_proj",
|
| 288 |
+
"model.layers.11.mlp_hyper_connection.input_mix_weight_down",
|
| 289 |
+
"model.layers.11.self_attn.indexer.index_qk_proj",
|
| 290 |
+
"model.layers.11.self_attn.k_proj",
|
| 291 |
+
"model.layers.11.self_attn.o_proj",
|
| 292 |
+
"model.layers.11.self_attn.q_proj",
|
| 293 |
+
"model.layers.11.self_attn.v_proj",
|
| 294 |
+
"model.layers.12.attn_hyper_connection.input_mix_weight_down",
|
| 295 |
+
"model.layers.12.linear_attn.in_proj_a",
|
| 296 |
+
"model.layers.12.linear_attn.in_proj_b",
|
| 297 |
+
"model.layers.12.linear_attn.in_proj_qkv",
|
| 298 |
+
"model.layers.12.linear_attn.in_proj_z",
|
| 299 |
+
"model.layers.12.linear_attn.out_proj",
|
| 300 |
+
"model.layers.12.mlp.shared_expert.down_proj",
|
| 301 |
+
"model.layers.12.mlp.shared_expert.gate_proj",
|
| 302 |
+
"model.layers.12.mlp.shared_expert.up_proj",
|
| 303 |
+
"model.layers.12.mlp.switch_mlp.down_proj",
|
| 304 |
+
"model.layers.12.mlp.switch_mlp.gate_proj",
|
| 305 |
+
"model.layers.12.mlp.switch_mlp.up_proj",
|
| 306 |
+
"model.layers.12.mlp_hyper_connection.input_mix_weight_down",
|
| 307 |
+
"model.layers.13.attn_hyper_connection.input_mix_weight_down",
|
| 308 |
+
"model.layers.13.linear_attn.in_proj_a",
|
| 309 |
+
"model.layers.13.linear_attn.in_proj_b",
|
| 310 |
+
"model.layers.13.linear_attn.in_proj_qkv",
|
| 311 |
+
"model.layers.13.linear_attn.in_proj_z",
|
| 312 |
+
"model.layers.13.linear_attn.out_proj",
|
| 313 |
+
"model.layers.13.mlp.shared_expert.down_proj",
|
| 314 |
+
"model.layers.13.mlp.shared_expert.gate_proj",
|
| 315 |
+
"model.layers.13.mlp.shared_expert.up_proj",
|
| 316 |
+
"model.layers.13.mlp.switch_mlp.down_proj",
|
| 317 |
+
"model.layers.13.mlp.switch_mlp.gate_proj",
|
| 318 |
+
"model.layers.13.mlp.switch_mlp.up_proj",
|
| 319 |
+
"model.layers.13.mlp_hyper_connection.input_mix_weight_down",
|
| 320 |
+
"model.layers.14.attn_hyper_connection.input_mix_weight_down",
|
| 321 |
+
"model.layers.14.linear_attn.in_proj_a",
|
| 322 |
+
"model.layers.14.linear_attn.in_proj_b",
|
| 323 |
+
"model.layers.14.linear_attn.in_proj_qkv",
|
| 324 |
+
"model.layers.14.linear_attn.in_proj_z",
|
| 325 |
+
"model.layers.14.linear_attn.out_proj",
|
| 326 |
+
"model.layers.14.mlp.shared_expert.down_proj",
|
| 327 |
+
"model.layers.14.mlp.shared_expert.gate_proj",
|
| 328 |
+
"model.layers.14.mlp.shared_expert.up_proj",
|
| 329 |
+
"model.layers.14.mlp.switch_mlp.down_proj",
|
| 330 |
+
"model.layers.14.mlp.switch_mlp.gate_proj",
|
| 331 |
+
"model.layers.14.mlp.switch_mlp.up_proj",
|
| 332 |
+
"model.layers.14.mlp_hyper_connection.input_mix_weight_down",
|
| 333 |
+
"model.layers.15.attn_hyper_connection.input_mix_weight_down",
|
| 334 |
+
"model.layers.15.mlp.shared_expert.down_proj",
|
| 335 |
+
"model.layers.15.mlp.shared_expert.gate_proj",
|
| 336 |
+
"model.layers.15.mlp.shared_expert.up_proj",
|
| 337 |
+
"model.layers.15.mlp.switch_mlp.down_proj",
|
| 338 |
+
"model.layers.15.mlp.switch_mlp.gate_proj",
|
| 339 |
+
"model.layers.15.mlp.switch_mlp.up_proj",
|
| 340 |
+
"model.layers.15.mlp_hyper_connection.input_mix_weight_down",
|
| 341 |
+
"model.layers.15.self_attn.indexer.index_qk_proj",
|
| 342 |
+
"model.layers.15.self_attn.k_proj",
|
| 343 |
+
"model.layers.15.self_attn.o_proj",
|
| 344 |
+
"model.layers.15.self_attn.q_proj",
|
| 345 |
+
"model.layers.15.self_attn.v_proj",
|
| 346 |
+
"model.layers.16.attn_hyper_connection.input_mix_weight_down",
|
| 347 |
+
"model.layers.16.linear_attn.in_proj_a",
|
| 348 |
+
"model.layers.16.linear_attn.in_proj_b",
|
| 349 |
+
"model.layers.16.linear_attn.in_proj_qkv",
|
| 350 |
+
"model.layers.16.linear_attn.in_proj_z",
|
| 351 |
+
"model.layers.16.linear_attn.out_proj",
|
| 352 |
+
"model.layers.16.mlp.shared_expert.down_proj",
|
| 353 |
+
"model.layers.16.mlp.shared_expert.gate_proj",
|
| 354 |
+
"model.layers.16.mlp.shared_expert.up_proj",
|
| 355 |
+
"model.layers.16.mlp.switch_mlp.down_proj",
|
| 356 |
+
"model.layers.16.mlp.switch_mlp.gate_proj",
|
| 357 |
+
"model.layers.16.mlp.switch_mlp.up_proj",
|
| 358 |
+
"model.layers.16.mlp_hyper_connection.input_mix_weight_down",
|
| 359 |
+
"model.layers.17.attn_hyper_connection.input_mix_weight_down",
|
| 360 |
+
"model.layers.17.linear_attn.in_proj_a",
|
| 361 |
+
"model.layers.17.linear_attn.in_proj_b",
|
| 362 |
+
"model.layers.17.linear_attn.in_proj_qkv",
|
| 363 |
+
"model.layers.17.linear_attn.in_proj_z",
|
| 364 |
+
"model.layers.17.linear_attn.out_proj",
|
| 365 |
+
"model.layers.17.mlp.shared_expert.down_proj",
|
| 366 |
+
"model.layers.17.mlp.shared_expert.gate_proj",
|
| 367 |
+
"model.layers.17.mlp.shared_expert.up_proj",
|
| 368 |
+
"model.layers.17.mlp.switch_mlp.down_proj",
|
| 369 |
+
"model.layers.17.mlp.switch_mlp.gate_proj",
|
| 370 |
+
"model.layers.17.mlp.switch_mlp.up_proj",
|
| 371 |
+
"model.layers.17.mlp_hyper_connection.input_mix_weight_down",
|
| 372 |
+
"model.layers.18.attn_hyper_connection.input_mix_weight_down",
|
| 373 |
+
"model.layers.18.linear_attn.in_proj_a",
|
| 374 |
+
"model.layers.18.linear_attn.in_proj_b",
|
| 375 |
+
"model.layers.18.linear_attn.in_proj_qkv",
|
| 376 |
+
"model.layers.18.linear_attn.in_proj_z",
|
| 377 |
+
"model.layers.18.linear_attn.out_proj",
|
| 378 |
+
"model.layers.18.mlp.shared_expert.down_proj",
|
| 379 |
+
"model.layers.18.mlp.shared_expert.gate_proj",
|
| 380 |
+
"model.layers.18.mlp.shared_expert.up_proj",
|
| 381 |
+
"model.layers.18.mlp.switch_mlp.down_proj",
|
| 382 |
+
"model.layers.18.mlp.switch_mlp.gate_proj",
|
| 383 |
+
"model.layers.18.mlp.switch_mlp.up_proj",
|
| 384 |
+
"model.layers.18.mlp_hyper_connection.input_mix_weight_down",
|
| 385 |
+
"model.layers.19.attn_hyper_connection.input_mix_weight_down",
|
| 386 |
+
"model.layers.19.mlp.shared_expert.down_proj",
|
| 387 |
+
"model.layers.19.mlp.shared_expert.gate_proj",
|
| 388 |
+
"model.layers.19.mlp.shared_expert.up_proj",
|
| 389 |
+
"model.layers.19.mlp.switch_mlp.down_proj",
|
| 390 |
+
"model.layers.19.mlp.switch_mlp.gate_proj",
|
| 391 |
+
"model.layers.19.mlp.switch_mlp.up_proj",
|
| 392 |
+
"model.layers.19.mlp_hyper_connection.input_mix_weight_down",
|
| 393 |
+
"model.layers.19.self_attn.indexer.index_qk_proj",
|
| 394 |
+
"model.layers.19.self_attn.k_proj",
|
| 395 |
+
"model.layers.19.self_attn.o_proj",
|
| 396 |
+
"model.layers.19.self_attn.q_proj",
|
| 397 |
+
"model.layers.19.self_attn.v_proj",
|
| 398 |
+
"model.layers.2.attn_hyper_connection.input_mix_weight_down",
|
| 399 |
+
"model.layers.2.linear_attn.in_proj_a",
|
| 400 |
+
"model.layers.2.linear_attn.in_proj_b",
|
| 401 |
+
"model.layers.2.linear_attn.in_proj_qkv",
|
| 402 |
+
"model.layers.2.linear_attn.in_proj_z",
|
| 403 |
+
"model.layers.2.linear_attn.out_proj",
|
| 404 |
+
"model.layers.2.mlp.shared_expert.down_proj",
|
| 405 |
+
"model.layers.2.mlp.shared_expert.gate_proj",
|
| 406 |
+
"model.layers.2.mlp.shared_expert.up_proj",
|
| 407 |
+
"model.layers.2.mlp.switch_mlp.down_proj",
|
| 408 |
+
"model.layers.2.mlp.switch_mlp.gate_proj",
|
| 409 |
+
"model.layers.2.mlp.switch_mlp.up_proj",
|
| 410 |
+
"model.layers.2.mlp_hyper_connection.input_mix_weight_down",
|
| 411 |
+
"model.layers.20.attn_hyper_connection.input_mix_weight_down",
|
| 412 |
+
"model.layers.20.linear_attn.in_proj_a",
|
| 413 |
+
"model.layers.20.linear_attn.in_proj_b",
|
| 414 |
+
"model.layers.20.linear_attn.in_proj_qkv",
|
| 415 |
+
"model.layers.20.linear_attn.in_proj_z",
|
| 416 |
+
"model.layers.20.linear_attn.out_proj",
|
| 417 |
+
"model.layers.20.mlp.shared_expert.down_proj",
|
| 418 |
+
"model.layers.20.mlp.shared_expert.gate_proj",
|
| 419 |
+
"model.layers.20.mlp.shared_expert.up_proj",
|
| 420 |
+
"model.layers.20.mlp.switch_mlp.down_proj",
|
| 421 |
+
"model.layers.20.mlp.switch_mlp.gate_proj",
|
| 422 |
+
"model.layers.20.mlp.switch_mlp.up_proj",
|
| 423 |
+
"model.layers.20.mlp_hyper_connection.input_mix_weight_down",
|
| 424 |
+
"model.layers.21.attn_hyper_connection.input_mix_weight_down",
|
| 425 |
+
"model.layers.21.linear_attn.in_proj_a",
|
| 426 |
+
"model.layers.21.linear_attn.in_proj_b",
|
| 427 |
+
"model.layers.21.linear_attn.in_proj_qkv",
|
| 428 |
+
"model.layers.21.linear_attn.in_proj_z",
|
| 429 |
+
"model.layers.21.linear_attn.out_proj",
|
| 430 |
+
"model.layers.21.mlp.shared_expert.down_proj",
|
| 431 |
+
"model.layers.21.mlp.shared_expert.gate_proj",
|
| 432 |
+
"model.layers.21.mlp.shared_expert.up_proj",
|
| 433 |
+
"model.layers.21.mlp.switch_mlp.down_proj",
|
| 434 |
+
"model.layers.21.mlp.switch_mlp.gate_proj",
|
| 435 |
+
"model.layers.21.mlp.switch_mlp.up_proj",
|
| 436 |
+
"model.layers.21.mlp_hyper_connection.input_mix_weight_down",
|
| 437 |
+
"model.layers.22.attn_hyper_connection.input_mix_weight_down",
|
| 438 |
+
"model.layers.22.linear_attn.in_proj_a",
|
| 439 |
+
"model.layers.22.linear_attn.in_proj_b",
|
| 440 |
+
"model.layers.22.linear_attn.in_proj_qkv",
|
| 441 |
+
"model.layers.22.linear_attn.in_proj_z",
|
| 442 |
+
"model.layers.22.linear_attn.out_proj",
|
| 443 |
+
"model.layers.22.mlp.shared_expert.down_proj",
|
| 444 |
+
"model.layers.22.mlp.shared_expert.gate_proj",
|
| 445 |
+
"model.layers.22.mlp.shared_expert.up_proj",
|
| 446 |
+
"model.layers.22.mlp.switch_mlp.down_proj",
|
| 447 |
+
"model.layers.22.mlp.switch_mlp.gate_proj",
|
| 448 |
+
"model.layers.22.mlp.switch_mlp.up_proj",
|
| 449 |
+
"model.layers.22.mlp_hyper_connection.input_mix_weight_down",
|
| 450 |
+
"model.layers.23.attn_hyper_connection.input_mix_weight_down",
|
| 451 |
+
"model.layers.23.mlp.shared_expert.down_proj",
|
| 452 |
+
"model.layers.23.mlp.shared_expert.gate_proj",
|
| 453 |
+
"model.layers.23.mlp.shared_expert.up_proj",
|
| 454 |
+
"model.layers.23.mlp.switch_mlp.down_proj",
|
| 455 |
+
"model.layers.23.mlp.switch_mlp.gate_proj",
|
| 456 |
+
"model.layers.23.mlp.switch_mlp.up_proj",
|
| 457 |
+
"model.layers.23.mlp_hyper_connection.input_mix_weight_down",
|
| 458 |
+
"model.layers.23.self_attn.indexer.index_qk_proj",
|
| 459 |
+
"model.layers.23.self_attn.k_proj",
|
| 460 |
+
"model.layers.23.self_attn.o_proj",
|
| 461 |
+
"model.layers.23.self_attn.q_proj",
|
| 462 |
+
"model.layers.23.self_attn.v_proj",
|
| 463 |
+
"model.layers.24.attn_hyper_connection.input_mix_weight_down",
|
| 464 |
+
"model.layers.24.linear_attn.in_proj_a",
|
| 465 |
+
"model.layers.24.linear_attn.in_proj_b",
|
| 466 |
+
"model.layers.24.linear_attn.in_proj_qkv",
|
| 467 |
+
"model.layers.24.linear_attn.in_proj_z",
|
| 468 |
+
"model.layers.24.linear_attn.out_proj",
|
| 469 |
+
"model.layers.24.mlp.shared_expert.down_proj",
|
| 470 |
+
"model.layers.24.mlp.shared_expert.gate_proj",
|
| 471 |
+
"model.layers.24.mlp.shared_expert.up_proj",
|
| 472 |
+
"model.layers.24.mlp.switch_mlp.down_proj",
|
| 473 |
+
"model.layers.24.mlp.switch_mlp.gate_proj",
|
| 474 |
+
"model.layers.24.mlp.switch_mlp.up_proj",
|
| 475 |
+
"model.layers.24.mlp_hyper_connection.input_mix_weight_down",
|
| 476 |
+
"model.layers.25.attn_hyper_connection.input_mix_weight_down",
|
| 477 |
+
"model.layers.25.linear_attn.in_proj_a",
|
| 478 |
+
"model.layers.25.linear_attn.in_proj_b",
|
| 479 |
+
"model.layers.25.linear_attn.in_proj_qkv",
|
| 480 |
+
"model.layers.25.linear_attn.in_proj_z",
|
| 481 |
+
"model.layers.25.linear_attn.out_proj",
|
| 482 |
+
"model.layers.25.mlp.shared_expert.down_proj",
|
| 483 |
+
"model.layers.25.mlp.shared_expert.gate_proj",
|
| 484 |
+
"model.layers.25.mlp.shared_expert.up_proj",
|
| 485 |
+
"model.layers.25.mlp.switch_mlp.down_proj",
|
| 486 |
+
"model.layers.25.mlp.switch_mlp.gate_proj",
|
| 487 |
+
"model.layers.25.mlp.switch_mlp.up_proj",
|
| 488 |
+
"model.layers.25.mlp_hyper_connection.input_mix_weight_down",
|
| 489 |
+
"model.layers.26.attn_hyper_connection.input_mix_weight_down",
|
| 490 |
+
"model.layers.26.linear_attn.in_proj_a",
|
| 491 |
+
"model.layers.26.linear_attn.in_proj_b",
|
| 492 |
+
"model.layers.26.linear_attn.in_proj_qkv",
|
| 493 |
+
"model.layers.26.linear_attn.in_proj_z",
|
| 494 |
+
"model.layers.26.linear_attn.out_proj",
|
| 495 |
+
"model.layers.26.mlp.shared_expert.down_proj",
|
| 496 |
+
"model.layers.26.mlp.shared_expert.gate_proj",
|
| 497 |
+
"model.layers.26.mlp.shared_expert.up_proj",
|
| 498 |
+
"model.layers.26.mlp.switch_mlp.down_proj",
|
| 499 |
+
"model.layers.26.mlp.switch_mlp.gate_proj",
|
| 500 |
+
"model.layers.26.mlp.switch_mlp.up_proj",
|
| 501 |
+
"model.layers.26.mlp_hyper_connection.input_mix_weight_down",
|
| 502 |
+
"model.layers.27.attn_hyper_connection.input_mix_weight_down",
|
| 503 |
+
"model.layers.27.mlp.shared_expert.down_proj",
|
| 504 |
+
"model.layers.27.mlp.shared_expert.gate_proj",
|
| 505 |
+
"model.layers.27.mlp.shared_expert.up_proj",
|
| 506 |
+
"model.layers.27.mlp.switch_mlp.down_proj",
|
| 507 |
+
"model.layers.27.mlp.switch_mlp.gate_proj",
|
| 508 |
+
"model.layers.27.mlp.switch_mlp.up_proj",
|
| 509 |
+
"model.layers.27.mlp_hyper_connection.input_mix_weight_down",
|
| 510 |
+
"model.layers.27.self_attn.indexer.index_qk_proj",
|
| 511 |
+
"model.layers.27.self_attn.k_proj",
|
| 512 |
+
"model.layers.27.self_attn.o_proj",
|
| 513 |
+
"model.layers.27.self_attn.q_proj",
|
| 514 |
+
"model.layers.27.self_attn.v_proj",
|
| 515 |
+
"model.layers.28.attn_hyper_connection.input_mix_weight_down",
|
| 516 |
+
"model.layers.28.linear_attn.in_proj_a",
|
| 517 |
+
"model.layers.28.linear_attn.in_proj_b",
|
| 518 |
+
"model.layers.28.linear_attn.in_proj_qkv",
|
| 519 |
+
"model.layers.28.linear_attn.in_proj_z",
|
| 520 |
+
"model.layers.28.linear_attn.out_proj",
|
| 521 |
+
"model.layers.28.mlp.shared_expert.down_proj",
|
| 522 |
+
"model.layers.28.mlp.shared_expert.gate_proj",
|
| 523 |
+
"model.layers.28.mlp.shared_expert.up_proj",
|
| 524 |
+
"model.layers.28.mlp.switch_mlp.down_proj",
|
| 525 |
+
"model.layers.28.mlp.switch_mlp.gate_proj",
|
| 526 |
+
"model.layers.28.mlp.switch_mlp.up_proj",
|
| 527 |
+
"model.layers.28.mlp_hyper_connection.input_mix_weight_down",
|
| 528 |
+
"model.layers.29.attn_hyper_connection.input_mix_weight_down",
|
| 529 |
+
"model.layers.29.linear_attn.in_proj_a",
|
| 530 |
+
"model.layers.29.linear_attn.in_proj_b",
|
| 531 |
+
"model.layers.29.linear_attn.in_proj_qkv",
|
| 532 |
+
"model.layers.29.linear_attn.in_proj_z",
|
| 533 |
+
"model.layers.29.linear_attn.out_proj",
|
| 534 |
+
"model.layers.29.mlp.shared_expert.down_proj",
|
| 535 |
+
"model.layers.29.mlp.shared_expert.gate_proj",
|
| 536 |
+
"model.layers.29.mlp.shared_expert.up_proj",
|
| 537 |
+
"model.layers.29.mlp.switch_mlp.down_proj",
|
| 538 |
+
"model.layers.29.mlp.switch_mlp.gate_proj",
|
| 539 |
+
"model.layers.29.mlp.switch_mlp.up_proj",
|
| 540 |
+
"model.layers.29.mlp_hyper_connection.input_mix_weight_down",
|
| 541 |
+
"model.layers.3.attn_hyper_connection.input_mix_weight_down",
|
| 542 |
+
"model.layers.3.mlp.shared_expert.down_proj",
|
| 543 |
+
"model.layers.3.mlp.shared_expert.gate_proj",
|
| 544 |
+
"model.layers.3.mlp.shared_expert.up_proj",
|
| 545 |
+
"model.layers.3.mlp.switch_mlp.down_proj",
|
| 546 |
+
"model.layers.3.mlp.switch_mlp.gate_proj",
|
| 547 |
+
"model.layers.3.mlp.switch_mlp.up_proj",
|
| 548 |
+
"model.layers.3.mlp_hyper_connection.input_mix_weight_down",
|
| 549 |
+
"model.layers.3.self_attn.indexer.index_qk_proj",
|
| 550 |
+
"model.layers.3.self_attn.k_proj",
|
| 551 |
+
"model.layers.3.self_attn.o_proj",
|
| 552 |
+
"model.layers.3.self_attn.q_proj",
|
| 553 |
+
"model.layers.3.self_attn.v_proj",
|
| 554 |
+
"model.layers.30.attn_hyper_connection.input_mix_weight_down",
|
| 555 |
+
"model.layers.30.linear_attn.in_proj_a",
|
| 556 |
+
"model.layers.30.linear_attn.in_proj_b",
|
| 557 |
+
"model.layers.30.linear_attn.in_proj_qkv",
|
| 558 |
+
"model.layers.30.linear_attn.in_proj_z",
|
| 559 |
+
"model.layers.30.linear_attn.out_proj",
|
| 560 |
+
"model.layers.30.mlp.shared_expert.down_proj",
|
| 561 |
+
"model.layers.30.mlp.shared_expert.gate_proj",
|
| 562 |
+
"model.layers.30.mlp.shared_expert.up_proj",
|
| 563 |
+
"model.layers.30.mlp.switch_mlp.down_proj",
|
| 564 |
+
"model.layers.30.mlp.switch_mlp.gate_proj",
|
| 565 |
+
"model.layers.30.mlp.switch_mlp.up_proj",
|
| 566 |
+
"model.layers.30.mlp_hyper_connection.input_mix_weight_down",
|
| 567 |
+
"model.layers.31.attn_hyper_connection.input_mix_weight_down",
|
| 568 |
+
"model.layers.31.mlp.shared_expert.down_proj",
|
| 569 |
+
"model.layers.31.mlp.shared_expert.gate_proj",
|
| 570 |
+
"model.layers.31.mlp.shared_expert.up_proj",
|
| 571 |
+
"model.layers.31.mlp.switch_mlp.down_proj",
|
| 572 |
+
"model.layers.31.mlp.switch_mlp.gate_proj",
|
| 573 |
+
"model.layers.31.mlp.switch_mlp.up_proj",
|
| 574 |
+
"model.layers.31.mlp_hyper_connection.input_mix_weight_down",
|
| 575 |
+
"model.layers.31.self_attn.indexer.index_qk_proj",
|
| 576 |
+
"model.layers.31.self_attn.k_proj",
|
| 577 |
+
"model.layers.31.self_attn.o_proj",
|
| 578 |
+
"model.layers.31.self_attn.q_proj",
|
| 579 |
+
"model.layers.31.self_attn.v_proj",
|
| 580 |
+
"model.layers.32.attn_hyper_connection.input_mix_weight_down",
|
| 581 |
+
"model.layers.32.linear_attn.in_proj_a",
|
| 582 |
+
"model.layers.32.linear_attn.in_proj_b",
|
| 583 |
+
"model.layers.32.linear_attn.in_proj_qkv",
|
| 584 |
+
"model.layers.32.linear_attn.in_proj_z",
|
| 585 |
+
"model.layers.32.linear_attn.out_proj",
|
| 586 |
+
"model.layers.32.mlp.shared_expert.down_proj",
|
| 587 |
+
"model.layers.32.mlp.shared_expert.gate_proj",
|
| 588 |
+
"model.layers.32.mlp.shared_expert.up_proj",
|
| 589 |
+
"model.layers.32.mlp.switch_mlp.down_proj",
|
| 590 |
+
"model.layers.32.mlp.switch_mlp.gate_proj",
|
| 591 |
+
"model.layers.32.mlp.switch_mlp.up_proj",
|
| 592 |
+
"model.layers.32.mlp_hyper_connection.input_mix_weight_down",
|
| 593 |
+
"model.layers.33.attn_hyper_connection.input_mix_weight_down",
|
| 594 |
+
"model.layers.33.linear_attn.in_proj_a",
|
| 595 |
+
"model.layers.33.linear_attn.in_proj_b",
|
| 596 |
+
"model.layers.33.linear_attn.in_proj_qkv",
|
| 597 |
+
"model.layers.33.linear_attn.in_proj_z",
|
| 598 |
+
"model.layers.33.linear_attn.out_proj",
|
| 599 |
+
"model.layers.33.mlp.shared_expert.down_proj",
|
| 600 |
+
"model.layers.33.mlp.shared_expert.gate_proj",
|
| 601 |
+
"model.layers.33.mlp.shared_expert.up_proj",
|
| 602 |
+
"model.layers.33.mlp.switch_mlp.down_proj",
|
| 603 |
+
"model.layers.33.mlp.switch_mlp.gate_proj",
|
| 604 |
+
"model.layers.33.mlp.switch_mlp.up_proj",
|
| 605 |
+
"model.layers.33.mlp_hyper_connection.input_mix_weight_down",
|
| 606 |
+
"model.layers.34.attn_hyper_connection.input_mix_weight_down",
|
| 607 |
+
"model.layers.34.linear_attn.in_proj_a",
|
| 608 |
+
"model.layers.34.linear_attn.in_proj_b",
|
| 609 |
+
"model.layers.34.linear_attn.in_proj_qkv",
|
| 610 |
+
"model.layers.34.linear_attn.in_proj_z",
|
| 611 |
+
"model.layers.34.linear_attn.out_proj",
|
| 612 |
+
"model.layers.34.mlp.shared_expert.down_proj",
|
| 613 |
+
"model.layers.34.mlp.shared_expert.gate_proj",
|
| 614 |
+
"model.layers.34.mlp.shared_expert.up_proj",
|
| 615 |
+
"model.layers.34.mlp.switch_mlp.down_proj",
|
| 616 |
+
"model.layers.34.mlp.switch_mlp.gate_proj",
|
| 617 |
+
"model.layers.34.mlp.switch_mlp.up_proj",
|
| 618 |
+
"model.layers.34.mlp_hyper_connection.input_mix_weight_down",
|
| 619 |
+
"model.layers.35.attn_hyper_connection.input_mix_weight_down",
|
| 620 |
+
"model.layers.35.mlp.shared_expert.down_proj",
|
| 621 |
+
"model.layers.35.mlp.shared_expert.gate_proj",
|
| 622 |
+
"model.layers.35.mlp.shared_expert.up_proj",
|
| 623 |
+
"model.layers.35.mlp.switch_mlp.down_proj",
|
| 624 |
+
"model.layers.35.mlp.switch_mlp.gate_proj",
|
| 625 |
+
"model.layers.35.mlp.switch_mlp.up_proj",
|
| 626 |
+
"model.layers.35.mlp_hyper_connection.input_mix_weight_down",
|
| 627 |
+
"model.layers.35.self_attn.indexer.index_qk_proj",
|
| 628 |
+
"model.layers.35.self_attn.k_proj",
|
| 629 |
+
"model.layers.35.self_attn.o_proj",
|
| 630 |
+
"model.layers.35.self_attn.q_proj",
|
| 631 |
+
"model.layers.35.self_attn.v_proj",
|
| 632 |
+
"model.layers.36.attn_hyper_connection.input_mix_weight_down",
|
| 633 |
+
"model.layers.36.linear_attn.in_proj_a",
|
| 634 |
+
"model.layers.36.linear_attn.in_proj_b",
|
| 635 |
+
"model.layers.36.linear_attn.in_proj_qkv",
|
| 636 |
+
"model.layers.36.linear_attn.in_proj_z",
|
| 637 |
+
"model.layers.36.linear_attn.out_proj",
|
| 638 |
+
"model.layers.36.mlp.shared_expert.down_proj",
|
| 639 |
+
"model.layers.36.mlp.shared_expert.gate_proj",
|
| 640 |
+
"model.layers.36.mlp.shared_expert.up_proj",
|
| 641 |
+
"model.layers.36.mlp.switch_mlp.down_proj",
|
| 642 |
+
"model.layers.36.mlp.switch_mlp.gate_proj",
|
| 643 |
+
"model.layers.36.mlp.switch_mlp.up_proj",
|
| 644 |
+
"model.layers.36.mlp_hyper_connection.input_mix_weight_down",
|
| 645 |
+
"model.layers.37.attn_hyper_connection.input_mix_weight_down",
|
| 646 |
+
"model.layers.37.linear_attn.in_proj_a",
|
| 647 |
+
"model.layers.37.linear_attn.in_proj_b",
|
| 648 |
+
"model.layers.37.linear_attn.in_proj_qkv",
|
| 649 |
+
"model.layers.37.linear_attn.in_proj_z",
|
| 650 |
+
"model.layers.37.linear_attn.out_proj",
|
| 651 |
+
"model.layers.37.mlp.shared_expert.down_proj",
|
| 652 |
+
"model.layers.37.mlp.shared_expert.gate_proj",
|
| 653 |
+
"model.layers.37.mlp.shared_expert.up_proj",
|
| 654 |
+
"model.layers.37.mlp.switch_mlp.down_proj",
|
| 655 |
+
"model.layers.37.mlp.switch_mlp.gate_proj",
|
| 656 |
+
"model.layers.37.mlp.switch_mlp.up_proj",
|
| 657 |
+
"model.layers.37.mlp_hyper_connection.input_mix_weight_down",
|
| 658 |
+
"model.layers.38.attn_hyper_connection.input_mix_weight_down",
|
| 659 |
+
"model.layers.38.linear_attn.in_proj_a",
|
| 660 |
+
"model.layers.38.linear_attn.in_proj_b",
|
| 661 |
+
"model.layers.38.linear_attn.in_proj_qkv",
|
| 662 |
+
"model.layers.38.linear_attn.in_proj_z",
|
| 663 |
+
"model.layers.38.linear_attn.out_proj",
|
| 664 |
+
"model.layers.38.mlp.shared_expert.down_proj",
|
| 665 |
+
"model.layers.38.mlp.shared_expert.gate_proj",
|
| 666 |
+
"model.layers.38.mlp.shared_expert.up_proj",
|
| 667 |
+
"model.layers.38.mlp.switch_mlp.down_proj",
|
| 668 |
+
"model.layers.38.mlp.switch_mlp.gate_proj",
|
| 669 |
+
"model.layers.38.mlp.switch_mlp.up_proj",
|
| 670 |
+
"model.layers.38.mlp_hyper_connection.input_mix_weight_down",
|
| 671 |
+
"model.layers.39.attn_hyper_connection.input_mix_weight_down",
|
| 672 |
+
"model.layers.39.mlp.shared_expert.down_proj",
|
| 673 |
+
"model.layers.39.mlp.shared_expert.gate_proj",
|
| 674 |
+
"model.layers.39.mlp.shared_expert.up_proj",
|
| 675 |
+
"model.layers.39.mlp.switch_mlp.down_proj",
|
| 676 |
+
"model.layers.39.mlp.switch_mlp.gate_proj",
|
| 677 |
+
"model.layers.39.mlp.switch_mlp.up_proj",
|
| 678 |
+
"model.layers.39.mlp_hyper_connection.input_mix_weight_down",
|
| 679 |
+
"model.layers.39.self_attn.indexer.index_qk_proj",
|
| 680 |
+
"model.layers.39.self_attn.k_proj",
|
| 681 |
+
"model.layers.39.self_attn.o_proj",
|
| 682 |
+
"model.layers.39.self_attn.q_proj",
|
| 683 |
+
"model.layers.39.self_attn.v_proj",
|
| 684 |
+
"model.layers.4.attn_hyper_connection.input_mix_weight_down",
|
| 685 |
+
"model.layers.4.linear_attn.in_proj_a",
|
| 686 |
+
"model.layers.4.linear_attn.in_proj_b",
|
| 687 |
+
"model.layers.4.linear_attn.in_proj_qkv",
|
| 688 |
+
"model.layers.4.linear_attn.in_proj_z",
|
| 689 |
+
"model.layers.4.linear_attn.out_proj",
|
| 690 |
+
"model.layers.4.mlp.shared_expert.down_proj",
|
| 691 |
+
"model.layers.4.mlp.shared_expert.gate_proj",
|
| 692 |
+
"model.layers.4.mlp.shared_expert.up_proj",
|
| 693 |
+
"model.layers.4.mlp.switch_mlp.down_proj",
|
| 694 |
+
"model.layers.4.mlp.switch_mlp.gate_proj",
|
| 695 |
+
"model.layers.4.mlp.switch_mlp.up_proj",
|
| 696 |
+
"model.layers.4.mlp_hyper_connection.input_mix_weight_down",
|
| 697 |
+
"model.layers.40.attn_hyper_connection.input_mix_weight_down",
|
| 698 |
+
"model.layers.40.linear_attn.in_proj_a",
|
| 699 |
+
"model.layers.40.linear_attn.in_proj_b",
|
| 700 |
+
"model.layers.40.linear_attn.in_proj_qkv",
|
| 701 |
+
"model.layers.40.linear_attn.in_proj_z",
|
| 702 |
+
"model.layers.40.linear_attn.out_proj",
|
| 703 |
+
"model.layers.40.mlp.shared_expert.down_proj",
|
| 704 |
+
"model.layers.40.mlp.shared_expert.gate_proj",
|
| 705 |
+
"model.layers.40.mlp.shared_expert.up_proj",
|
| 706 |
+
"model.layers.40.mlp.switch_mlp.down_proj",
|
| 707 |
+
"model.layers.40.mlp.switch_mlp.gate_proj",
|
| 708 |
+
"model.layers.40.mlp.switch_mlp.up_proj",
|
| 709 |
+
"model.layers.40.mlp_hyper_connection.input_mix_weight_down",
|
| 710 |
+
"model.layers.41.attn_hyper_connection.input_mix_weight_down",
|
| 711 |
+
"model.layers.41.linear_attn.in_proj_a",
|
| 712 |
+
"model.layers.41.linear_attn.in_proj_b",
|
| 713 |
+
"model.layers.41.linear_attn.in_proj_qkv",
|
| 714 |
+
"model.layers.41.linear_attn.in_proj_z",
|
| 715 |
+
"model.layers.41.linear_attn.out_proj",
|
| 716 |
+
"model.layers.41.mlp.shared_expert.down_proj",
|
| 717 |
+
"model.layers.41.mlp.shared_expert.gate_proj",
|
| 718 |
+
"model.layers.41.mlp.shared_expert.up_proj",
|
| 719 |
+
"model.layers.41.mlp.switch_mlp.down_proj",
|
| 720 |
+
"model.layers.41.mlp.switch_mlp.gate_proj",
|
| 721 |
+
"model.layers.41.mlp.switch_mlp.up_proj",
|
| 722 |
+
"model.layers.41.mlp_hyper_connection.input_mix_weight_down",
|
| 723 |
+
"model.layers.42.attn_hyper_connection.input_mix_weight_down",
|
| 724 |
+
"model.layers.42.linear_attn.in_proj_a",
|
| 725 |
+
"model.layers.42.linear_attn.in_proj_b",
|
| 726 |
+
"model.layers.42.linear_attn.in_proj_qkv",
|
| 727 |
+
"model.layers.42.linear_attn.in_proj_z",
|
| 728 |
+
"model.layers.42.linear_attn.out_proj",
|
| 729 |
+
"model.layers.42.mlp.shared_expert.down_proj",
|
| 730 |
+
"model.layers.42.mlp.shared_expert.gate_proj",
|
| 731 |
+
"model.layers.42.mlp.shared_expert.up_proj",
|
| 732 |
+
"model.layers.42.mlp.switch_mlp.down_proj",
|
| 733 |
+
"model.layers.42.mlp.switch_mlp.gate_proj",
|
| 734 |
+
"model.layers.42.mlp.switch_mlp.up_proj",
|
| 735 |
+
"model.layers.42.mlp_hyper_connection.input_mix_weight_down",
|
| 736 |
+
"model.layers.43.attn_hyper_connection.input_mix_weight_down",
|
| 737 |
+
"model.layers.43.mlp.shared_expert.down_proj",
|
| 738 |
+
"model.layers.43.mlp.shared_expert.gate_proj",
|
| 739 |
+
"model.layers.43.mlp.shared_expert.up_proj",
|
| 740 |
+
"model.layers.43.mlp.switch_mlp.down_proj",
|
| 741 |
+
"model.layers.43.mlp.switch_mlp.gate_proj",
|
| 742 |
+
"model.layers.43.mlp.switch_mlp.up_proj",
|
| 743 |
+
"model.layers.43.mlp_hyper_connection.input_mix_weight_down",
|
| 744 |
+
"model.layers.43.self_attn.indexer.index_qk_proj",
|
| 745 |
+
"model.layers.43.self_attn.k_proj",
|
| 746 |
+
"model.layers.43.self_attn.o_proj",
|
| 747 |
+
"model.layers.43.self_attn.q_proj",
|
| 748 |
+
"model.layers.43.self_attn.v_proj",
|
| 749 |
+
"model.layers.44.attn_hyper_connection.input_mix_weight_down",
|
| 750 |
+
"model.layers.44.linear_attn.in_proj_a",
|
| 751 |
+
"model.layers.44.linear_attn.in_proj_b",
|
| 752 |
+
"model.layers.44.linear_attn.in_proj_qkv",
|
| 753 |
+
"model.layers.44.linear_attn.in_proj_z",
|
| 754 |
+
"model.layers.44.linear_attn.out_proj",
|
| 755 |
+
"model.layers.44.mlp.shared_expert.down_proj",
|
| 756 |
+
"model.layers.44.mlp.shared_expert.gate_proj",
|
| 757 |
+
"model.layers.44.mlp.shared_expert.up_proj",
|
| 758 |
+
"model.layers.44.mlp.switch_mlp.down_proj",
|
| 759 |
+
"model.layers.44.mlp.switch_mlp.gate_proj",
|
| 760 |
+
"model.layers.44.mlp.switch_mlp.up_proj",
|
| 761 |
+
"model.layers.44.mlp_hyper_connection.input_mix_weight_down",
|
| 762 |
+
"model.layers.45.attn_hyper_connection.input_mix_weight_down",
|
| 763 |
+
"model.layers.45.linear_attn.in_proj_a",
|
| 764 |
+
"model.layers.45.linear_attn.in_proj_b",
|
| 765 |
+
"model.layers.45.linear_attn.in_proj_qkv",
|
| 766 |
+
"model.layers.45.linear_attn.in_proj_z",
|
| 767 |
+
"model.layers.45.linear_attn.out_proj",
|
| 768 |
+
"model.layers.45.mlp.shared_expert.down_proj",
|
| 769 |
+
"model.layers.45.mlp.shared_expert.gate_proj",
|
| 770 |
+
"model.layers.45.mlp.shared_expert.up_proj",
|
| 771 |
+
"model.layers.45.mlp.switch_mlp.down_proj",
|
| 772 |
+
"model.layers.45.mlp.switch_mlp.gate_proj",
|
| 773 |
+
"model.layers.45.mlp.switch_mlp.up_proj",
|
| 774 |
+
"model.layers.45.mlp_hyper_connection.input_mix_weight_down",
|
| 775 |
+
"model.layers.46.attn_hyper_connection.input_mix_weight_down",
|
| 776 |
+
"model.layers.46.linear_attn.in_proj_a",
|
| 777 |
+
"model.layers.46.linear_attn.in_proj_b",
|
| 778 |
+
"model.layers.46.linear_attn.in_proj_qkv",
|
| 779 |
+
"model.layers.46.linear_attn.in_proj_z",
|
| 780 |
+
"model.layers.46.linear_attn.out_proj",
|
| 781 |
+
"model.layers.46.mlp.shared_expert.down_proj",
|
| 782 |
+
"model.layers.46.mlp.shared_expert.gate_proj",
|
| 783 |
+
"model.layers.46.mlp.shared_expert.up_proj",
|
| 784 |
+
"model.layers.46.mlp.switch_mlp.down_proj",
|
| 785 |
+
"model.layers.46.mlp.switch_mlp.gate_proj",
|
| 786 |
+
"model.layers.46.mlp.switch_mlp.up_proj",
|
| 787 |
+
"model.layers.46.mlp_hyper_connection.input_mix_weight_down",
|
| 788 |
+
"model.layers.47.attn_hyper_connection.input_mix_weight_down",
|
| 789 |
+
"model.layers.47.mlp.shared_expert.down_proj",
|
| 790 |
+
"model.layers.47.mlp.shared_expert.gate_proj",
|
| 791 |
+
"model.layers.47.mlp.shared_expert.up_proj",
|
| 792 |
+
"model.layers.47.mlp.switch_mlp.down_proj",
|
| 793 |
+
"model.layers.47.mlp.switch_mlp.gate_proj",
|
| 794 |
+
"model.layers.47.mlp.switch_mlp.up_proj",
|
| 795 |
+
"model.layers.47.mlp_hyper_connection.input_mix_weight_down",
|
| 796 |
+
"model.layers.47.self_attn.indexer.index_qk_proj",
|
| 797 |
+
"model.layers.47.self_attn.k_proj",
|
| 798 |
+
"model.layers.47.self_attn.o_proj",
|
| 799 |
+
"model.layers.47.self_attn.q_proj",
|
| 800 |
+
"model.layers.47.self_attn.v_proj",
|
| 801 |
+
"model.layers.5.attn_hyper_connection.input_mix_weight_down",
|
| 802 |
+
"model.layers.5.linear_attn.in_proj_a",
|
| 803 |
+
"model.layers.5.linear_attn.in_proj_b",
|
| 804 |
+
"model.layers.5.linear_attn.in_proj_qkv",
|
| 805 |
+
"model.layers.5.linear_attn.in_proj_z",
|
| 806 |
+
"model.layers.5.linear_attn.out_proj",
|
| 807 |
+
"model.layers.5.mlp.shared_expert.down_proj",
|
| 808 |
+
"model.layers.5.mlp.shared_expert.gate_proj",
|
| 809 |
+
"model.layers.5.mlp.shared_expert.up_proj",
|
| 810 |
+
"model.layers.5.mlp.switch_mlp.down_proj",
|
| 811 |
+
"model.layers.5.mlp.switch_mlp.gate_proj",
|
| 812 |
+
"model.layers.5.mlp.switch_mlp.up_proj",
|
| 813 |
+
"model.layers.5.mlp_hyper_connection.input_mix_weight_down",
|
| 814 |
+
"model.layers.6.attn_hyper_connection.input_mix_weight_down",
|
| 815 |
+
"model.layers.6.linear_attn.in_proj_a",
|
| 816 |
+
"model.layers.6.linear_attn.in_proj_b",
|
| 817 |
+
"model.layers.6.linear_attn.in_proj_qkv",
|
| 818 |
+
"model.layers.6.linear_attn.in_proj_z",
|
| 819 |
+
"model.layers.6.linear_attn.out_proj",
|
| 820 |
+
"model.layers.6.mlp.shared_expert.down_proj",
|
| 821 |
+
"model.layers.6.mlp.shared_expert.gate_proj",
|
| 822 |
+
"model.layers.6.mlp.shared_expert.up_proj",
|
| 823 |
+
"model.layers.6.mlp.switch_mlp.down_proj",
|
| 824 |
+
"model.layers.6.mlp.switch_mlp.gate_proj",
|
| 825 |
+
"model.layers.6.mlp.switch_mlp.up_proj",
|
| 826 |
+
"model.layers.6.mlp_hyper_connection.input_mix_weight_down",
|
| 827 |
+
"model.layers.7.attn_hyper_connection.input_mix_weight_down",
|
| 828 |
+
"model.layers.7.mlp.shared_expert.down_proj",
|
| 829 |
+
"model.layers.7.mlp.shared_expert.gate_proj",
|
| 830 |
+
"model.layers.7.mlp.shared_expert.up_proj",
|
| 831 |
+
"model.layers.7.mlp.switch_mlp.down_proj",
|
| 832 |
+
"model.layers.7.mlp.switch_mlp.gate_proj",
|
| 833 |
+
"model.layers.7.mlp.switch_mlp.up_proj",
|
| 834 |
+
"model.layers.7.mlp_hyper_connection.input_mix_weight_down",
|
| 835 |
+
"model.layers.7.self_attn.indexer.index_qk_proj",
|
| 836 |
+
"model.layers.7.self_attn.k_proj",
|
| 837 |
+
"model.layers.7.self_attn.o_proj",
|
| 838 |
+
"model.layers.7.self_attn.q_proj",
|
| 839 |
+
"model.layers.7.self_attn.v_proj",
|
| 840 |
+
"model.layers.8.attn_hyper_connection.input_mix_weight_down",
|
| 841 |
+
"model.layers.8.linear_attn.in_proj_a",
|
| 842 |
+
"model.layers.8.linear_attn.in_proj_b",
|
| 843 |
+
"model.layers.8.linear_attn.in_proj_qkv",
|
| 844 |
+
"model.layers.8.linear_attn.in_proj_z",
|
| 845 |
+
"model.layers.8.linear_attn.out_proj",
|
| 846 |
+
"model.layers.8.mlp.shared_expert.down_proj",
|
| 847 |
+
"model.layers.8.mlp.shared_expert.gate_proj",
|
| 848 |
+
"model.layers.8.mlp.shared_expert.up_proj",
|
| 849 |
+
"model.layers.8.mlp.switch_mlp.down_proj",
|
| 850 |
+
"model.layers.8.mlp.switch_mlp.gate_proj",
|
| 851 |
+
"model.layers.8.mlp.switch_mlp.up_proj",
|
| 852 |
+
"model.layers.8.mlp_hyper_connection.input_mix_weight_down",
|
| 853 |
+
"model.layers.9.attn_hyper_connection.input_mix_weight_down",
|
| 854 |
+
"model.layers.9.linear_attn.in_proj_a",
|
| 855 |
+
"model.layers.9.linear_attn.in_proj_b",
|
| 856 |
+
"model.layers.9.linear_attn.in_proj_qkv",
|
| 857 |
+
"model.layers.9.linear_attn.in_proj_z",
|
| 858 |
+
"model.layers.9.linear_attn.out_proj",
|
| 859 |
+
"model.layers.9.mlp.shared_expert.down_proj",
|
| 860 |
+
"model.layers.9.mlp.shared_expert.gate_proj",
|
| 861 |
+
"model.layers.9.mlp.shared_expert.up_proj",
|
| 862 |
+
"model.layers.9.mlp.switch_mlp.down_proj",
|
| 863 |
+
"model.layers.9.mlp.switch_mlp.gate_proj",
|
| 864 |
+
"model.layers.9.mlp.switch_mlp.up_proj",
|
| 865 |
+
"model.layers.9.mlp_hyper_connection.input_mix_weight_down"
|
| 866 |
+
],
|
| 867 |
+
"missing": [],
|
| 868 |
+
"mismatched": [],
|
| 869 |
+
"zero_count_experts": 63
|
| 870 |
+
}
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0997f410c57a1f4e53b09e4be8f4a172d90edd9564368fb0847030937229b9f3
|
| 3 |
+
size 12809320
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_prefix_space": false,
|
| 3 |
+
"added_tokens_decoder": {
|
| 4 |
+
"248044": {
|
| 5 |
+
"content": "<|endoftext|>",
|
| 6 |
+
"lstrip": false,
|
| 7 |
+
"normalized": false,
|
| 8 |
+
"rstrip": false,
|
| 9 |
+
"single_word": false,
|
| 10 |
+
"special": true
|
| 11 |
+
},
|
| 12 |
+
"248045": {
|
| 13 |
+
"content": "<|im_start|>",
|
| 14 |
+
"lstrip": false,
|
| 15 |
+
"normalized": false,
|
| 16 |
+
"rstrip": false,
|
| 17 |
+
"single_word": false,
|
| 18 |
+
"special": true
|
| 19 |
+
},
|
| 20 |
+
"248046": {
|
| 21 |
+
"content": "<|im_end|>",
|
| 22 |
+
"lstrip": false,
|
| 23 |
+
"normalized": false,
|
| 24 |
+
"rstrip": false,
|
| 25 |
+
"single_word": false,
|
| 26 |
+
"special": true
|
| 27 |
+
},
|
| 28 |
+
"248047": {
|
| 29 |
+
"content": "<|object_ref_start|>",
|
| 30 |
+
"lstrip": false,
|
| 31 |
+
"normalized": false,
|
| 32 |
+
"rstrip": false,
|
| 33 |
+
"single_word": false,
|
| 34 |
+
"special": true
|
| 35 |
+
},
|
| 36 |
+
"248048": {
|
| 37 |
+
"content": "<|object_ref_end|>",
|
| 38 |
+
"lstrip": false,
|
| 39 |
+
"normalized": false,
|
| 40 |
+
"rstrip": false,
|
| 41 |
+
"single_word": false,
|
| 42 |
+
"special": true
|
| 43 |
+
},
|
| 44 |
+
"248049": {
|
| 45 |
+
"content": "<|box_start|>",
|
| 46 |
+
"lstrip": false,
|
| 47 |
+
"normalized": false,
|
| 48 |
+
"rstrip": false,
|
| 49 |
+
"single_word": false,
|
| 50 |
+
"special": true
|
| 51 |
+
},
|
| 52 |
+
"248050": {
|
| 53 |
+
"content": "<|box_end|>",
|
| 54 |
+
"lstrip": false,
|
| 55 |
+
"normalized": false,
|
| 56 |
+
"rstrip": false,
|
| 57 |
+
"single_word": false,
|
| 58 |
+
"special": true
|
| 59 |
+
},
|
| 60 |
+
"248051": {
|
| 61 |
+
"content": "<|quad_start|>",
|
| 62 |
+
"lstrip": false,
|
| 63 |
+
"normalized": false,
|
| 64 |
+
"rstrip": false,
|
| 65 |
+
"single_word": false,
|
| 66 |
+
"special": true
|
| 67 |
+
},
|
| 68 |
+
"248052": {
|
| 69 |
+
"content": "<|quad_end|>",
|
| 70 |
+
"lstrip": false,
|
| 71 |
+
"normalized": false,
|
| 72 |
+
"rstrip": false,
|
| 73 |
+
"single_word": false,
|
| 74 |
+
"special": true
|
| 75 |
+
},
|
| 76 |
+
"248053": {
|
| 77 |
+
"content": "<|vision_start|>",
|
| 78 |
+
"lstrip": false,
|
| 79 |
+
"normalized": false,
|
| 80 |
+
"rstrip": false,
|
| 81 |
+
"single_word": false,
|
| 82 |
+
"special": true
|
| 83 |
+
},
|
| 84 |
+
"248054": {
|
| 85 |
+
"content": "<|vision_end|>",
|
| 86 |
+
"lstrip": false,
|
| 87 |
+
"normalized": false,
|
| 88 |
+
"rstrip": false,
|
| 89 |
+
"single_word": false,
|
| 90 |
+
"special": true
|
| 91 |
+
},
|
| 92 |
+
"248055": {
|
| 93 |
+
"content": "<|vision_pad|>",
|
| 94 |
+
"lstrip": false,
|
| 95 |
+
"normalized": false,
|
| 96 |
+
"rstrip": false,
|
| 97 |
+
"single_word": false,
|
| 98 |
+
"special": true
|
| 99 |
+
},
|
| 100 |
+
"248056": {
|
| 101 |
+
"content": "<|image_pad|>",
|
| 102 |
+
"lstrip": false,
|
| 103 |
+
"normalized": false,
|
| 104 |
+
"rstrip": false,
|
| 105 |
+
"single_word": false,
|
| 106 |
+
"special": true
|
| 107 |
+
},
|
| 108 |
+
"248057": {
|
| 109 |
+
"content": "<|video_pad|>",
|
| 110 |
+
"lstrip": false,
|
| 111 |
+
"normalized": false,
|
| 112 |
+
"rstrip": false,
|
| 113 |
+
"single_word": false,
|
| 114 |
+
"special": true
|
| 115 |
+
},
|
| 116 |
+
"248058": {
|
| 117 |
+
"content": "<tool_call>",
|
| 118 |
+
"lstrip": false,
|
| 119 |
+
"normalized": false,
|
| 120 |
+
"rstrip": false,
|
| 121 |
+
"single_word": false,
|
| 122 |
+
"special": false
|
| 123 |
+
},
|
| 124 |
+
"248059": {
|
| 125 |
+
"content": "</tool_call>",
|
| 126 |
+
"lstrip": false,
|
| 127 |
+
"normalized": false,
|
| 128 |
+
"rstrip": false,
|
| 129 |
+
"single_word": false,
|
| 130 |
+
"special": false
|
| 131 |
+
},
|
| 132 |
+
"248060": {
|
| 133 |
+
"content": "<|fim_prefix|>",
|
| 134 |
+
"lstrip": false,
|
| 135 |
+
"normalized": false,
|
| 136 |
+
"rstrip": false,
|
| 137 |
+
"single_word": false,
|
| 138 |
+
"special": false
|
| 139 |
+
},
|
| 140 |
+
"248061": {
|
| 141 |
+
"content": "<|fim_middle|>",
|
| 142 |
+
"lstrip": false,
|
| 143 |
+
"normalized": false,
|
| 144 |
+
"rstrip": false,
|
| 145 |
+
"single_word": false,
|
| 146 |
+
"special": false
|
| 147 |
+
},
|
| 148 |
+
"248062": {
|
| 149 |
+
"content": "<|fim_suffix|>",
|
| 150 |
+
"lstrip": false,
|
| 151 |
+
"normalized": false,
|
| 152 |
+
"rstrip": false,
|
| 153 |
+
"single_word": false,
|
| 154 |
+
"special": false
|
| 155 |
+
},
|
| 156 |
+
"248063": {
|
| 157 |
+
"content": "<|fim_pad|>",
|
| 158 |
+
"lstrip": false,
|
| 159 |
+
"normalized": false,
|
| 160 |
+
"rstrip": false,
|
| 161 |
+
"single_word": false,
|
| 162 |
+
"special": false
|
| 163 |
+
},
|
| 164 |
+
"248064": {
|
| 165 |
+
"content": "<|repo_name|>",
|
| 166 |
+
"lstrip": false,
|
| 167 |
+
"normalized": false,
|
| 168 |
+
"rstrip": false,
|
| 169 |
+
"single_word": false,
|
| 170 |
+
"special": false
|
| 171 |
+
},
|
| 172 |
+
"248065": {
|
| 173 |
+
"content": "<|file_sep|>",
|
| 174 |
+
"lstrip": false,
|
| 175 |
+
"normalized": false,
|
| 176 |
+
"rstrip": false,
|
| 177 |
+
"single_word": false,
|
| 178 |
+
"special": false
|
| 179 |
+
},
|
| 180 |
+
"248066": {
|
| 181 |
+
"content": "<tool_response>",
|
| 182 |
+
"lstrip": false,
|
| 183 |
+
"normalized": false,
|
| 184 |
+
"rstrip": false,
|
| 185 |
+
"single_word": false,
|
| 186 |
+
"special": false
|
| 187 |
+
},
|
| 188 |
+
"248067": {
|
| 189 |
+
"content": "</tool_response>",
|
| 190 |
+
"lstrip": false,
|
| 191 |
+
"normalized": false,
|
| 192 |
+
"rstrip": false,
|
| 193 |
+
"single_word": false,
|
| 194 |
+
"special": false
|
| 195 |
+
},
|
| 196 |
+
"248068": {
|
| 197 |
+
"content": "<think>",
|
| 198 |
+
"lstrip": false,
|
| 199 |
+
"normalized": false,
|
| 200 |
+
"rstrip": false,
|
| 201 |
+
"single_word": false,
|
| 202 |
+
"special": false
|
| 203 |
+
},
|
| 204 |
+
"248069": {
|
| 205 |
+
"content": "</think>",
|
| 206 |
+
"lstrip": false,
|
| 207 |
+
"normalized": false,
|
| 208 |
+
"rstrip": false,
|
| 209 |
+
"single_word": false,
|
| 210 |
+
"special": false
|
| 211 |
+
},
|
| 212 |
+
"248070": {
|
| 213 |
+
"content": "<|audio_start|>",
|
| 214 |
+
"lstrip": false,
|
| 215 |
+
"normalized": false,
|
| 216 |
+
"rstrip": false,
|
| 217 |
+
"single_word": false,
|
| 218 |
+
"special": true
|
| 219 |
+
},
|
| 220 |
+
"248071": {
|
| 221 |
+
"content": "<|audio_end|>",
|
| 222 |
+
"lstrip": false,
|
| 223 |
+
"normalized": false,
|
| 224 |
+
"rstrip": false,
|
| 225 |
+
"single_word": false,
|
| 226 |
+
"special": true
|
| 227 |
+
},
|
| 228 |
+
"248072": {
|
| 229 |
+
"content": "<tts_pad>",
|
| 230 |
+
"lstrip": false,
|
| 231 |
+
"normalized": false,
|
| 232 |
+
"rstrip": false,
|
| 233 |
+
"single_word": false,
|
| 234 |
+
"special": true
|
| 235 |
+
},
|
| 236 |
+
"248073": {
|
| 237 |
+
"content": "<tts_text_bos>",
|
| 238 |
+
"lstrip": false,
|
| 239 |
+
"normalized": false,
|
| 240 |
+
"rstrip": false,
|
| 241 |
+
"single_word": false,
|
| 242 |
+
"special": true
|
| 243 |
+
},
|
| 244 |
+
"248074": {
|
| 245 |
+
"content": "<tts_text_eod>",
|
| 246 |
+
"lstrip": false,
|
| 247 |
+
"normalized": false,
|
| 248 |
+
"rstrip": false,
|
| 249 |
+
"single_word": false,
|
| 250 |
+
"special": true
|
| 251 |
+
},
|
| 252 |
+
"248075": {
|
| 253 |
+
"content": "<tts_text_bos_single>",
|
| 254 |
+
"lstrip": false,
|
| 255 |
+
"normalized": false,
|
| 256 |
+
"rstrip": false,
|
| 257 |
+
"single_word": false,
|
| 258 |
+
"special": true
|
| 259 |
+
},
|
| 260 |
+
"248076": {
|
| 261 |
+
"content": "<|audio_pad|>",
|
| 262 |
+
"lstrip": false,
|
| 263 |
+
"normalized": false,
|
| 264 |
+
"rstrip": false,
|
| 265 |
+
"single_word": false,
|
| 266 |
+
"special": true
|
| 267 |
+
}
|
| 268 |
+
},
|
| 269 |
+
"additional_special_tokens": [
|
| 270 |
+
"<|im_start|>",
|
| 271 |
+
"<|im_end|>",
|
| 272 |
+
"<|object_ref_start|>",
|
| 273 |
+
"<|object_ref_end|>",
|
| 274 |
+
"<|box_start|>",
|
| 275 |
+
"<|box_end|>",
|
| 276 |
+
"<|quad_start|>",
|
| 277 |
+
"<|quad_end|>",
|
| 278 |
+
"<|vision_start|>",
|
| 279 |
+
"<|vision_end|>",
|
| 280 |
+
"<|vision_pad|>",
|
| 281 |
+
"<|image_pad|>",
|
| 282 |
+
"<|video_pad|>"
|
| 283 |
+
],
|
| 284 |
+
"bos_token": null,
|
| 285 |
+
"chat_template": "{%- set image_count = namespace(value=0) %}\n{%- set video_count = namespace(value=0) %}\n{%- macro render_content(content, do_vision_count, is_system_content=false) %}\n {%- if content is string %}\n {{- content }}\n {%- elif content is iterable and content is not mapping %}\n {%- for item in content %}\n {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}\n {%- if is_system_content %}\n {{- raise_exception('System message cannot contain images.') }}\n {%- endif %}\n {%- if do_vision_count %}\n {%- set image_count.value = image_count.value + 1 %}\n {%- endif %}\n {%- if add_vision_id %}\n {{- 'Picture ' ~ image_count.value ~ ': ' }}\n {%- endif %}\n {{- '<|vision_start|><|image_pad|><|vision_end|>' }}\n {%- elif 'video' in item or item.type == 'video' %}\n {%- if is_system_content %}\n {{- raise_exception('System message cannot contain videos.') }}\n {%- endif %}\n {%- if do_vision_count %}\n {%- set video_count.value = video_count.value + 1 %}\n {%- endif %}\n {%- if add_vision_id %}\n {{- 'Video ' ~ video_count.value ~ ': ' }}\n {%- endif %}\n {{- '<|vision_start|><|video_pad|><|vision_end|>' }}\n {%- elif 'text' in item %}\n {{- item.text }}\n {%- else %}\n {{- raise_exception('Unexpected item type in content.') }}\n {%- endif %}\n {%- endfor %}\n {%- elif content is none or content is undefined %}\n {{- '' }}\n {%- else %}\n {{- raise_exception('Unexpected content type.') }}\n {%- endif %}\n{%- endmacro %}\n{%- if not messages %}\n {{- raise_exception('No messages provided.') }}\n{%- endif %}\n{%- set reasoning_instructions = '' %}\n{%- if enable_thinking is undefined or enable_thinking is true %}\n {%- set resolved_reasoning_effort = reasoning_effort|default('xhigh') %}\n {%- if resolved_reasoning_effort not in ('xhigh', 'medium', 'low') %}\n {{- raise_exception('Unexpected reasoning effort ' ~ reasoning_effort ~ '. Supported types are xhigh (default), medium, and low.') }}\n {%- endif %}\n {%- if resolved_reasoning_effort == 'xhigh' %}\n {%- set reasoning_instructions = 'Reasoning effort is set to xhigh. Please think carefully through the task, validate key assumptions, consider plausible alternatives, and prioritize correctness, consistency, and clarity in the final answer.' %}\n {%- elif resolved_reasoning_effort == 'low' %}\n {%- set reasoning_instructions = 'Reasoning effort is set to low. Keep your thinking brief and focused, moving directly to the conclusion without unnecessary elaboration.' %}\n {%- endif %}\n{%- endif %}\n{%- if tools and tools is iterable and tools is not mapping %}\n {{- '<|im_start|>system\\n' }}\n {%- if reasoning_instructions %}\n {{- reasoning_instructions + '\\n\\n' }}\n {%- endif %}\n {{- \"# Tools\\n\\nYou have access to the following functions:\\n\\n<tools>\" }}\n {%- for tool in tools %}\n {{- \"\\n\" }}\n {{- tool | tojson }}\n {%- endfor %}\n {{- \"\\n</tools>\" }}\n {{- '\\n\\nIf you choose to call a function ONLY reply in the following format with NO suffix:\\n\\n<tool_call>\\n<function=example_function_name>\\n<parameter=example_parameter_1>\\nvalue_1\\n</parameter>\\n<parameter=example_parameter_2>\\nThis is the value for the second parameter\\nthat can span\\nmultiple lines\\n</parameter>\\n</function>\\n</tool_call>\\n\\n<IMPORTANT>\\nReminder:\\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\\n- Required parameters MUST be specified\\n- You may provide optional reasoning for your function call in natural language BEFORE the function call, but NOT after\\n- If there is no function call available, answer the question like normal with your current knowledge and do not tell the user about function calls\\n</IMPORTANT>' }}\n {%- if messages[0].role == 'system' %}\n {%- set content = render_content(messages[0].content, false, true)|trim %}\n {%- if content %}\n {{- '\\n\\n' + content }}\n {%- endif %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n{%- else %}\n {%- if messages[0].role == 'system' %}\n {%- set content = render_content(messages[0].content, false, true)|trim %}\n {%- if content %}\n {{- '<|im_start|>system\\n' + (reasoning_instructions + '\\n\\n' if reasoning_instructions else '') + content + '<|im_end|>\\n' }}\n {%- elif reasoning_instructions %}\n {{- '<|im_start|>system\\n' + reasoning_instructions + '<|im_end|>\\n' }}\n {%- endif %}\n {%- elif reasoning_instructions %}\n {{- '<|im_start|>system\\n' + reasoning_instructions + '<|im_end|>\\n' }}\n {%- endif %}\n{%- endif %}\n{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}\n{%- for message in messages[::-1] %}\n {%- set index = (messages|length - 1) - loop.index0 %}\n {%- if ns.multi_step_tool and message.role == \"user\" %}\n {%- set content = render_content(message.content, false)|trim %}\n {%- if not(content.startswith('<tool_response>') and content.endswith('</tool_response>')) %}\n {%- set ns.multi_step_tool = false %}\n {%- set ns.last_query_index = index %}\n {%- endif %}\n {%- endif %}\n{%- endfor %}\n{%- if ns.multi_step_tool %}\n {{- raise_exception('No user query found in messages.') }}\n{%- endif %}\n{%- for message in messages %}\n {%- set content = render_content(message.content, true)|trim %}\n {%- if message.role == \"system\" %}\n {%- if not loop.first %}\n {{- raise_exception('System message must be at the beginning.') }}\n {%- endif %}\n {%- elif message.role == \"user\" %}\n {{- '<|im_start|>' + message.role + '\\n' + content + '<|im_end|>' + '\\n' }}\n {%- elif message.role == \"assistant\" %}\n {%- set reasoning_content = '' %}\n {%- if message.reasoning_content is string %}\n {%- set reasoning_content = message.reasoning_content %}\n {%- endif %}\n {%- set reasoning_content = reasoning_content|trim %}\n {%- if preserve_thinking is undefined or preserve_thinking is true or loop.index0 > ns.last_query_index %}\n {{- '<|im_start|>' + message.role + '\\n<think>\\n' + reasoning_content + '\\n</think>\\n\\n' + content }}\n {%- else %}\n {{- '<|im_start|>' + message.role + '\\n' + content }}\n {%- endif %}\n {%- if message.tool_calls and message.tool_calls is iterable and message.tool_calls is not mapping %}\n {%- for tool_call in message.tool_calls %}\n {%- if tool_call.function is defined %}\n {%- set tool_call = tool_call.function %}\n {%- endif %}\n {%- if loop.first %}\n {%- if content|trim %}\n {{- '\\n\\n<tool_call>\\n<function=' + tool_call.name + '>\\n' }}\n {%- else %}\n {{- '<tool_call>\\n<function=' + tool_call.name + '>\\n' }}\n {%- endif %}\n {%- else %}\n {{- '\\n<tool_call>\\n<function=' + tool_call.name + '>\\n' }}\n {%- endif %}\n {%- if tool_call.arguments is defined and tool_call.arguments != '' %}\n {%- for args_name, args_value in tool_call.arguments|items %}\n {{- '<parameter=' + args_name + '>\\n' }}\n {%- set args_value = args_value | string if args_value is string else args_value | tojson | safe %}\n {{- args_value }}\n {{- '\\n</parameter>\\n' }}\n {%- endfor %}\n {%- endif %}\n {{- '</function>\\n</tool_call>' }}\n {%- endfor %}\n {%- endif %}\n {{- '<|im_end|>\\n' }}\n {%- elif message.role == \"tool\" %}\n {%- if loop.previtem and loop.previtem.role != \"tool\" %}\n {{- '<|im_start|>user' }}\n {%- endif %}\n {{- '\\n<tool_response>\\n' }}\n {{- content }}\n {{- '\\n</tool_response>' }}\n {%- if not loop.last and loop.nextitem.role != \"tool\" %}\n {{- '<|im_end|>\\n' }}\n {%- elif loop.last %}\n {{- '<|im_end|>\\n' }}\n {%- endif %}\n {%- else %}\n {{- raise_exception('Unexpected message role.') }}\n {%- endif %}\n{%- endfor %}\n{%- if add_generation_prompt %}\n {{- '<|im_start|>assistant\\n' }}\n {%- if enable_thinking is defined and enable_thinking is false %}\n {{- '<think>\\n\\n</think>\\n\\n' }}\n {%- else %}\n {{- '<think>\\n' }}\n {%- endif %}\n{%- endif %}",
|
| 286 |
+
"clean_up_tokenization_spaces": false,
|
| 287 |
+
"eos_token": "<|im_end|>",
|
| 288 |
+
"errors": "replace",
|
| 289 |
+
"model_max_length": 262144,
|
| 290 |
+
"pad_token": "<|endoftext|>",
|
| 291 |
+
"split_special_tokens": false,
|
| 292 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 293 |
+
"unk_token": null,
|
| 294 |
+
"add_bos_token": false,
|
| 295 |
+
"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+",
|
| 296 |
+
"extra_special_tokens": {
|
| 297 |
+
"audio_bos_token": "<|audio_start|>",
|
| 298 |
+
"audio_eos_token": "<|audio_end|>",
|
| 299 |
+
"audio_token": "<|audio_pad|>",
|
| 300 |
+
"image_token": "<|image_pad|>",
|
| 301 |
+
"video_token": "<|video_pad|>",
|
| 302 |
+
"vision_bos_token": "<|vision_start|>",
|
| 303 |
+
"vision_eos_token": "<|vision_end|>"
|
| 304 |
+
}
|
| 305 |
+
}
|
vocab.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|