Text Generation
MLX
Safetensors
laguna
apple-silicon
laguna-m.1
Mixture of Experts
quantized
conversational
custom_code
Instructions to use ox-ox/Laguna-M.1-MLX-Q3 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use ox-ox/Laguna-M.1-MLX-Q3 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("ox-ox/Laguna-M.1-MLX-Q3") 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 ox-ox/Laguna-M.1-MLX-Q3 with Pi:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "ox-ox/Laguna-M.1-MLX-Q3"
Configure the model in Pi
# Install Pi: npm install -g @mariozechner/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "mlx-lm": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "ox-ox/Laguna-M.1-MLX-Q3" } ] } } }Run Pi
# Start Pi in your project directory: pi
- OpenClaw new
How to use ox-ox/Laguna-M.1-MLX-Q3 with OpenClaw:
Start the MLX server
# Install MLX LM: uv tool install mlx-lm # Start a local OpenAI-compatible server: mlx_lm.server --model "ox-ox/Laguna-M.1-MLX-Q3"
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 "ox-ox/Laguna-M.1-MLX-Q3" \ --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"
- MLX LM
How to use ox-ox/Laguna-M.1-MLX-Q3 with MLX LM:
Generate or start a chat session
# Install MLX LM uv tool install mlx-lm # Interactive chat REPL mlx_lm.chat --model "ox-ox/Laguna-M.1-MLX-Q3"
Run an OpenAI-compatible server
# Install MLX LM uv tool install mlx-lm # Start the server mlx_lm.server --model "ox-ox/Laguna-M.1-MLX-Q3" # Calling the OpenAI-compatible server with curl curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "ox-ox/Laguna-M.1-MLX-Q3", "messages": [ {"role": "user", "content": "Hello"} ] }' - Hermes Agent
How to use ox-ox/Laguna-M.1-MLX-Q3 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 "ox-ox/Laguna-M.1-MLX-Q3"
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 ox-ox/Laguna-M.1-MLX-Q3
Run Hermes
hermes
Commit ·
cbf2988
0
Parent(s):
Super-squash branch 'main' using huggingface_hub
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitattributes +35 -0
- README.md +70 -0
- chat_template.jinja +132 -0
- config.json +136 -0
- configuration_laguna.py +186 -0
- generation_config.json +13 -0
- laguna.py +357 -0
- model-00000.safetensors +3 -0
- model-00001.safetensors +3 -0
- model-00002.safetensors +3 -0
- model-00003.safetensors +3 -0
- model-00004.safetensors +3 -0
- model-00005.safetensors +3 -0
- model-00006.safetensors +3 -0
- model-00007.safetensors +3 -0
- model-00008.safetensors +3 -0
- model-00009.safetensors +3 -0
- model-00010.safetensors +3 -0
- model-00011.safetensors +3 -0
- model-00012.safetensors +3 -0
- model-00013.safetensors +3 -0
- model-00014.safetensors +3 -0
- model-00015.safetensors +3 -0
- model-00016.safetensors +3 -0
- model-00017.safetensors +3 -0
- model-00018.safetensors +3 -0
- model-00019.safetensors +3 -0
- model-00020.safetensors +3 -0
- model-00021.safetensors +3 -0
- model-00022.safetensors +3 -0
- model-00023.safetensors +3 -0
- model-00024.safetensors +3 -0
- model-00025.safetensors +3 -0
- model-00026.safetensors +3 -0
- model-00027.safetensors +3 -0
- model-00028.safetensors +3 -0
- model-00029.safetensors +3 -0
- model-00030.safetensors +3 -0
- model-00031.safetensors +3 -0
- model-00032.safetensors +3 -0
- model-00033.safetensors +3 -0
- model-00034.safetensors +3 -0
- model-00035.safetensors +3 -0
- model-00036.safetensors +3 -0
- model-00037.safetensors +3 -0
- model-00038.safetensors +3 -0
- model-00039.safetensors +3 -0
- model-00040.safetensors +3 -0
- model-00041.safetensors +3 -0
- model-00042.safetensors +3 -0
.gitattributes
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz 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
|
README.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: apache-2.0
|
| 3 |
+
base_model: poolside/Laguna-M.1
|
| 4 |
+
base_model_relation: quantized
|
| 5 |
+
library_name: mlx
|
| 6 |
+
pipeline_tag: text-generation
|
| 7 |
+
tags:
|
| 8 |
+
- mlx
|
| 9 |
+
- apple-silicon
|
| 10 |
+
- laguna
|
| 11 |
+
- laguna-m.1
|
| 12 |
+
- moe
|
| 13 |
+
- quantized
|
| 14 |
+
- conversational
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
# Laguna-M.1-MLX-Q3
|
| 18 |
+
|
| 19 |
+
A community **MLX** (Apple Silicon) build of Poolside's
|
| 20 |
+
[**Laguna M.1**](https://huggingface.co/poolside/Laguna-M.1) — a 225B-total /
|
| 21 |
+
23B-active Mixture-of-Experts model — quantized to **3-bit** so it runs locally on
|
| 22 |
+
a 128 GB Mac.
|
| 23 |
+
|
| 24 |
+
Poolside ships official support for vLLM, SGLang, Transformers and TRT-LLM (all CUDA
|
| 25 |
+
/ datacenter). This is the **Apple Silicon / edge** path.
|
| 26 |
+
|
| 27 |
+
> Not affiliated with Poolside. Weights © Poolside, Inc., released under Apache 2.0.
|
| 28 |
+
> Converted from the public release `poolside/Laguna-M.1-FP8` (weights verified
|
| 29 |
+
> byte-identical to the public checkpoint; tokenizer, chat template and generation
|
| 30 |
+
> config taken from the public release).
|
| 31 |
+
|
| 32 |
+
## Use
|
| 33 |
+
|
| 34 |
+
`laguna` isn't upstream in mlx-lm yet
|
| 35 |
+
([PR #1415](https://github.com/ml-explore/mlx-lm/pull/1415) pending). Until it
|
| 36 |
+
lands, install mlx-lm from the branch that ships the model file **and the
|
| 37 |
+
tool-call parser fix** (needed for tool use in agentic clients), pinned to a commit:
|
| 38 |
+
|
| 39 |
+
```bash
|
| 40 |
+
pip install "git+https://github.com/eauchs/mlx-lm.git@5b0c0667f4a8c25ee9bb9ef729ab64822d1b246e"
|
| 41 |
+
|
| 42 |
+
mlx_lm.generate --model ox-ox/Laguna-M.1-MLX-Q3 \
|
| 43 |
+
--prompt "Write a Python retry wrapper with exponential backoff." \
|
| 44 |
+
--temp 1.0 --top-k 20
|
| 45 |
+
```
|
| 46 |
+
|
| 47 |
+
Once the PR is merged, this is just `pip install -U mlx-lm` + the `mlx_lm.generate`
|
| 48 |
+
line — no extra step.
|
| 49 |
+
|
| 50 |
+
## Performance
|
| 51 |
+
|
| 52 |
+
| Quant | Hardware | Throughput | Peak RAM |
|
| 53 |
+
|-------|----------|-----------|----------|
|
| 54 |
+
| Q3 | Apple M3 Max 128 GB | ~26.5 tok/s | ~100 GB |
|
| 55 |
+
|
| 56 |
+
## Architecture
|
| 57 |
+
|
| 58 |
+
70 layers (3 dense SwiGLU + 67 sparse MoE), 256 experts + 1 shared, top-k=16 sigmoid
|
| 59 |
+
routing; global attention 64 Q / 8 KV heads, head_dim 128, QK-norm + softplus output
|
| 60 |
+
gating; RoPE with YaRN. See the [official model card](https://huggingface.co/poolside/Laguna-M.1)
|
| 61 |
+
for full details and benchmarks.
|
| 62 |
+
|
| 63 |
+
## License
|
| 64 |
+
|
| 65 |
+
Apache 2.0 (weights and conversion). © Poolside, Inc. for Laguna M.1.
|
| 66 |
+
|
| 67 |
+
## Citation
|
| 68 |
+
|
| 69 |
+
Conversion by Théophile Lafargue ([@eauchs](https://x.com/eauchs)). Model by
|
| 70 |
+
Poolside — see their [technical report](https://huggingface.co/poolside/Laguna-M.1).
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{#- Iteration on laguna_glm_thinking_v5/chat_template.jinja -#}
|
| 2 |
+
{#- Adds a default system message (used when no system message is provided in `messages`). -#}
|
| 3 |
+
{{- "〈|EOS|〉" -}}
|
| 4 |
+
{%- set enable_thinking = enable_thinking | default(false) -%}
|
| 5 |
+
{%- set render_assistant_messages_raw = render_assistant_messages_raw | default(false) -%}
|
| 6 |
+
{%- set add_generation_prompt = add_generation_prompt | default(false) -%}
|
| 7 |
+
|
| 8 |
+
{#- ───── header (system message) ───── -#}
|
| 9 |
+
{%- set system_message = "You are a helpful, conversationally-fluent assistant made by Poolside. You are here to be helpful to users through natural language conversations." -%}
|
| 10 |
+
{%- if messages and messages[0].role == "system" -%}
|
| 11 |
+
{%- set system_message = messages[0].content -%}
|
| 12 |
+
{%- endif -%}
|
| 13 |
+
|
| 14 |
+
{%- if (system_message and system_message.strip()) or tools -%}
|
| 15 |
+
{{- "<system>\n" -}}
|
| 16 |
+
|
| 17 |
+
{%- if system_message and system_message.strip() -%}
|
| 18 |
+
{{- "\n" -}}
|
| 19 |
+
{{- system_message.rstrip() -}}
|
| 20 |
+
{%- endif -%}
|
| 21 |
+
|
| 22 |
+
{%- if tools -%}
|
| 23 |
+
{{- "\n\n### Tools\n\n" -}}
|
| 24 |
+
{%- set ns = namespace(tool_string="You may call functions to assist with the user query.\n"
|
| 25 |
+
~ "All available function signatures are listed below:\n"
|
| 26 |
+
~ "<available_tools>\n") -%}
|
| 27 |
+
{%- for tool in tools -%}
|
| 28 |
+
{%- set ns.tool_string = ns.tool_string ~ (tool | tojson) ~ "\n" -%}
|
| 29 |
+
{%- endfor -%}
|
| 30 |
+
{%- if enable_thinking -%}
|
| 31 |
+
{%- set tool_string = ns.tool_string + "</available_tools>\n\n" ~
|
| 32 |
+
"Wrap your thinking in '<think>', '</think>' tags, followed by a function call. For each function call, return an unescaped XML-like object with function name and arguments within '<tool_call>' and '</tool_call>' tags, like here:\n" ~
|
| 33 |
+
"<think> your thoughts here </think>\n" ~
|
| 34 |
+
"<tool_call>function-name\n<arg_key>argument-key</arg_key>\n<arg_value>value-of-argument-key</arg_value>\n" ~
|
| 35 |
+
"</tool_call>" -%}
|
| 36 |
+
{%- else -%}
|
| 37 |
+
{%- set tool_string = ns.tool_string + "</available_tools>\n\n" ~
|
| 38 |
+
"For each function call, return an unescaped XML-like object " ~
|
| 39 |
+
"with function name and arguments within '<tool_call>' and '</tool_call>' tags, like here:\n" ~
|
| 40 |
+
"<tool_call>function-name\n<arg_key>argument-key</arg_key>\n<arg_value>value-of-argument-key</arg_value>\n" ~
|
| 41 |
+
"</tool_call>" -%}
|
| 42 |
+
{%- endif -%}
|
| 43 |
+
{{- tool_string -}}
|
| 44 |
+
{%- endif -%}
|
| 45 |
+
|
| 46 |
+
{{- "\n</system>\n" -}}
|
| 47 |
+
{%- endif -%}
|
| 48 |
+
|
| 49 |
+
{#- ───── main loop ───── -#}
|
| 50 |
+
{%- for message in messages -%}
|
| 51 |
+
{%- set content = message.content if message.content is string else "" -%}
|
| 52 |
+
{%- if message.role == "user" -%}
|
| 53 |
+
{{- "<user>\n" + content + "\n</user>\n" -}}
|
| 54 |
+
{%- elif message.role == "assistant" -%}
|
| 55 |
+
{%- generation -%}
|
| 56 |
+
{{- "<assistant>\n" -}}
|
| 57 |
+
{%- if render_assistant_messages_raw -%}
|
| 58 |
+
{#- Raw mode: prepend the generation prompt token, then dump content verbatim. -#}
|
| 59 |
+
{#- The generation prompt is <think> when enable_thinking, </think> otherwise. -#}
|
| 60 |
+
{#- Only prepend if content doesn't already start with it. -#}
|
| 61 |
+
{%- if enable_thinking -%}
|
| 62 |
+
{%- if not content.startswith('<think>') -%}
|
| 63 |
+
{{- '<think>' -}}
|
| 64 |
+
{%- endif -%}
|
| 65 |
+
{%- else -%}
|
| 66 |
+
{%- if not content.startswith('</think>') -%}
|
| 67 |
+
{{- '</think>' -}}
|
| 68 |
+
{%- endif -%}
|
| 69 |
+
{%- endif -%}
|
| 70 |
+
{{- content -}}
|
| 71 |
+
{#- Append closing tag if content doesn't already end with it. -#}
|
| 72 |
+
{%- if not content.endswith('</assistant>\n') and not content.endswith('</assistant>') -%}
|
| 73 |
+
{{- '\n</assistant>' -}}
|
| 74 |
+
{%- endif -%}
|
| 75 |
+
{{- "\n" -}}
|
| 76 |
+
{%- else -%}
|
| 77 |
+
{#- Extract reasoning content from message.reasoning (vLLM field name) or message.reasoning_content, or from <think> tags -#}
|
| 78 |
+
{%- set reasoning_content = '' %}
|
| 79 |
+
{%- if message.reasoning is string %}
|
| 80 |
+
{%- set reasoning_content = message.reasoning %}
|
| 81 |
+
{%- elif message.reasoning_content is string %}
|
| 82 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 83 |
+
{%- endif %}
|
| 84 |
+
{#- Always strip <think> tags from content if present to avoid duplication -#}
|
| 85 |
+
{%- if '</think>' in content %}
|
| 86 |
+
{%- if not reasoning_content %}
|
| 87 |
+
{%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
|
| 88 |
+
{%- endif %}
|
| 89 |
+
{%- set content = content.split('</think>')[-1].lstrip('\n') %}
|
| 90 |
+
{%- endif %}
|
| 91 |
+
{#- Display reasoning content for all messages -#}
|
| 92 |
+
{%- if reasoning_content -%}
|
| 93 |
+
{{- '<think>\n' + reasoning_content.strip() + '\n</think>\n' -}}
|
| 94 |
+
{%- else -%}
|
| 95 |
+
{{- '</think>\n' -}}
|
| 96 |
+
{%- endif -%}
|
| 97 |
+
{#- Display main content -#}
|
| 98 |
+
{%- if content.strip() -%}
|
| 99 |
+
{{- content.strip() ~ "\n" -}}
|
| 100 |
+
{%- endif -%}
|
| 101 |
+
{%- if message.tool_calls -%}
|
| 102 |
+
{%- for tool_call in message.tool_calls -%}
|
| 103 |
+
{%- set function_data = tool_call.function -%}
|
| 104 |
+
{{- '<tool_call>' + function_data.name }}
|
| 105 |
+
{% set _args = function_data.arguments %}
|
| 106 |
+
{%- for k, v in _args.items() -%}
|
| 107 |
+
{{- "<arg_key>" ~ k ~ "</arg_key>\n" -}}
|
| 108 |
+
{{- "<arg_value>"}}{{ v | tojson(ensure_ascii=False) if v is not string else v }}{{ "</arg_value>\n" -}}
|
| 109 |
+
{%- endfor -%}
|
| 110 |
+
{{- "</tool_call>\n" -}}
|
| 111 |
+
{%- endfor -%}
|
| 112 |
+
{%- endif -%}
|
| 113 |
+
{{- "</assistant>\n" -}}
|
| 114 |
+
{%- endif -%}
|
| 115 |
+
{%- endgeneration -%}
|
| 116 |
+
{%- elif message.role == "tool" -%}
|
| 117 |
+
{{- "<tool_response>\n" + content + "\n</tool_response>\n" -}}
|
| 118 |
+
{%- elif message.role == "system" and loop.index0 != 0 -%}
|
| 119 |
+
{#- Render additional system messages (skip the first one which is handled separately in the header) -#}
|
| 120 |
+
{{- "<system>\n" + content + "\n</system>\n" -}}
|
| 121 |
+
{%- endif -%}
|
| 122 |
+
{%- endfor -%}
|
| 123 |
+
{#- ───── generation prompt ───── -#}
|
| 124 |
+
{%- if add_generation_prompt -%}
|
| 125 |
+
{{- "<assistant>\n" -}}
|
| 126 |
+
{#- ───── Include reasoning mode directive ───── -#}
|
| 127 |
+
{%- if not enable_thinking %}
|
| 128 |
+
{{- '</think>' -}}
|
| 129 |
+
{%- else %}
|
| 130 |
+
{{- '<think>' -}}
|
| 131 |
+
{%- endif %}
|
| 132 |
+
{%- endif -%}
|
config.json
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"LagunaForCausalLM"
|
| 4 |
+
],
|
| 5 |
+
"attention_bias": false,
|
| 6 |
+
"attention_dropout": 0.0,
|
| 7 |
+
"auto_map": {
|
| 8 |
+
"AutoConfig": "configuration_laguna.LagunaConfig",
|
| 9 |
+
"AutoModelForCausalLM": "modeling_laguna.LagunaForCausalLM"
|
| 10 |
+
},
|
| 11 |
+
"bos_token_id": 2,
|
| 12 |
+
"eos_token_id": [
|
| 13 |
+
2,
|
| 14 |
+
24
|
| 15 |
+
],
|
| 16 |
+
"gating": "per-element",
|
| 17 |
+
"head_dim": 128,
|
| 18 |
+
"hidden_size": 4096,
|
| 19 |
+
"intermediate_size": 16384,
|
| 20 |
+
"max_position_embeddings": 131072,
|
| 21 |
+
"mlp_layer_types": [
|
| 22 |
+
"dense",
|
| 23 |
+
"dense",
|
| 24 |
+
"dense",
|
| 25 |
+
"sparse",
|
| 26 |
+
"sparse",
|
| 27 |
+
"sparse",
|
| 28 |
+
"sparse",
|
| 29 |
+
"sparse",
|
| 30 |
+
"sparse",
|
| 31 |
+
"sparse",
|
| 32 |
+
"sparse",
|
| 33 |
+
"sparse",
|
| 34 |
+
"sparse",
|
| 35 |
+
"sparse",
|
| 36 |
+
"sparse",
|
| 37 |
+
"sparse",
|
| 38 |
+
"sparse",
|
| 39 |
+
"sparse",
|
| 40 |
+
"sparse",
|
| 41 |
+
"sparse",
|
| 42 |
+
"sparse",
|
| 43 |
+
"sparse",
|
| 44 |
+
"sparse",
|
| 45 |
+
"sparse",
|
| 46 |
+
"sparse",
|
| 47 |
+
"sparse",
|
| 48 |
+
"sparse",
|
| 49 |
+
"sparse",
|
| 50 |
+
"sparse",
|
| 51 |
+
"sparse",
|
| 52 |
+
"sparse",
|
| 53 |
+
"sparse",
|
| 54 |
+
"sparse",
|
| 55 |
+
"sparse",
|
| 56 |
+
"sparse",
|
| 57 |
+
"sparse",
|
| 58 |
+
"sparse",
|
| 59 |
+
"sparse",
|
| 60 |
+
"sparse",
|
| 61 |
+
"sparse",
|
| 62 |
+
"sparse",
|
| 63 |
+
"sparse",
|
| 64 |
+
"sparse",
|
| 65 |
+
"sparse",
|
| 66 |
+
"sparse",
|
| 67 |
+
"sparse",
|
| 68 |
+
"sparse",
|
| 69 |
+
"sparse",
|
| 70 |
+
"sparse",
|
| 71 |
+
"sparse",
|
| 72 |
+
"sparse",
|
| 73 |
+
"sparse",
|
| 74 |
+
"sparse",
|
| 75 |
+
"sparse",
|
| 76 |
+
"sparse",
|
| 77 |
+
"sparse",
|
| 78 |
+
"sparse",
|
| 79 |
+
"sparse",
|
| 80 |
+
"sparse",
|
| 81 |
+
"sparse",
|
| 82 |
+
"sparse",
|
| 83 |
+
"sparse",
|
| 84 |
+
"sparse",
|
| 85 |
+
"sparse",
|
| 86 |
+
"sparse",
|
| 87 |
+
"sparse",
|
| 88 |
+
"sparse",
|
| 89 |
+
"sparse",
|
| 90 |
+
"sparse",
|
| 91 |
+
"sparse"
|
| 92 |
+
],
|
| 93 |
+
"model_type": "laguna",
|
| 94 |
+
"moe_apply_router_weight_on_input": false,
|
| 95 |
+
"moe_intermediate_size": 1024,
|
| 96 |
+
"moe_routed_scaling_factor": 1.0,
|
| 97 |
+
"num_attention_heads": 64,
|
| 98 |
+
"num_experts": 256,
|
| 99 |
+
"num_experts_per_tok": 16,
|
| 100 |
+
"num_hidden_layers": 70,
|
| 101 |
+
"num_key_value_heads": 8,
|
| 102 |
+
"pad_token_id": 9,
|
| 103 |
+
"partial_rotary_factor": 1.0,
|
| 104 |
+
"quantization": {
|
| 105 |
+
"group_size": 64,
|
| 106 |
+
"bits": 3
|
| 107 |
+
},
|
| 108 |
+
"rms_norm_eps": 1e-06,
|
| 109 |
+
"rope_parameters": {
|
| 110 |
+
"full_attention": {
|
| 111 |
+
"rope_theta": 500000.0,
|
| 112 |
+
"rope_type": "yarn",
|
| 113 |
+
"factor": 32.0,
|
| 114 |
+
"original_max_position_embeddings": 4096,
|
| 115 |
+
"beta_slow": 1.0,
|
| 116 |
+
"beta_fast": 64.0,
|
| 117 |
+
"attention_factor": 1.0
|
| 118 |
+
}
|
| 119 |
+
},
|
| 120 |
+
"rope_scaling": {
|
| 121 |
+
"rope_type": "yarn",
|
| 122 |
+
"factor": 32.0,
|
| 123 |
+
"original_max_position_embeddings": 4096,
|
| 124 |
+
"beta_slow": 1.0,
|
| 125 |
+
"beta_fast": 64.0,
|
| 126 |
+
"attention_factor": 1.0
|
| 127 |
+
},
|
| 128 |
+
"rope_theta": 500000.0,
|
| 129 |
+
"router_aux_loss_coef": 0.0,
|
| 130 |
+
"shared_expert_intermediate_size": 1024,
|
| 131 |
+
"tie_word_embeddings": false,
|
| 132 |
+
"torch_dtype": "bfloat16",
|
| 133 |
+
"use_bidirectional_attention": false,
|
| 134 |
+
"use_cache": true,
|
| 135 |
+
"vocab_size": 100352
|
| 136 |
+
}
|
configuration_laguna.py
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# ruff: noqa
|
| 2 |
+
# Copyright 2025 Poolside and the HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""
|
| 16 |
+
Laguna configuration for transformers 4.56-4.x (used by vLLM).
|
| 17 |
+
|
| 18 |
+
This uses rope_theta + rope_scaling (legacy format) instead of
|
| 19 |
+
rope_parameters (v5 format).
|
| 20 |
+
"""
|
| 21 |
+
|
| 22 |
+
from transformers.configuration_utils import PretrainedConfig
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class LagunaConfig(PretrainedConfig):
|
| 26 |
+
r"""
|
| 27 |
+
Configuration class for Laguna model.
|
| 28 |
+
|
| 29 |
+
Laguna is Poolside's MoE architecture with:
|
| 30 |
+
- Attention output gating (softplus gate)
|
| 31 |
+
- Sigmoid routing instead of softmax
|
| 32 |
+
- No QKV bias
|
| 33 |
+
- Explicit head_dim parameter
|
| 34 |
+
|
| 35 |
+
Args:
|
| 36 |
+
head_dim (`int`, *optional*, defaults to 128):
|
| 37 |
+
Dimension of attention heads. Laguna uses explicit head_dim rather than
|
| 38 |
+
computing it from hidden_size // num_attention_heads.
|
| 39 |
+
qkv_bias (`bool`, *optional*, defaults to `False`):
|
| 40 |
+
Whether to add bias to QKV projections. Laguna uses no QKV bias.
|
| 41 |
+
attention_bias (`bool`, *optional*, defaults to `False`):
|
| 42 |
+
Whether to add bias to attention output projection. Laguna uses no attention bias.
|
| 43 |
+
gating (`bool`, *optional*, defaults to `True`):
|
| 44 |
+
Whether to use softplus output gating on attention. When True, a g_proj linear
|
| 45 |
+
layer is added and attn_output = attn_output * softplus(g_proj(x)).
|
| 46 |
+
vocab_size (`int`, *optional*, defaults to 100352):
|
| 47 |
+
Vocabulary size of the Laguna model.
|
| 48 |
+
hidden_size (`int`, *optional*, defaults to 2048):
|
| 49 |
+
Dimension of the hidden representations.
|
| 50 |
+
intermediate_size (`int`, *optional*, defaults to 8192):
|
| 51 |
+
Dimension of the MLP representations for dense layers.
|
| 52 |
+
num_hidden_layers (`int`, *optional*, defaults to 48):
|
| 53 |
+
Number of hidden layers in the Transformer.
|
| 54 |
+
num_attention_heads (`int`, *optional*, defaults to 32):
|
| 55 |
+
Number of attention heads.
|
| 56 |
+
num_key_value_heads (`int`, *optional*, defaults to 8):
|
| 57 |
+
Number of key-value heads for GQA.
|
| 58 |
+
max_position_embeddings (`int`, *optional*, defaults to 4096):
|
| 59 |
+
Maximum sequence length.
|
| 60 |
+
rms_norm_eps (`float`, *optional*, defaults to 1e-6):
|
| 61 |
+
Epsilon for RMSNorm layers.
|
| 62 |
+
rope_theta (`float`, *optional*, defaults to 500000.0):
|
| 63 |
+
Base frequency for RoPE embeddings.
|
| 64 |
+
rope_scaling (`dict`, *optional*):
|
| 65 |
+
RoPE scaling configuration (e.g. YaRN, linear).
|
| 66 |
+
sliding_window (`int`, *optional*):
|
| 67 |
+
Sliding window attention size. Used by layers whose type in ``layer_types``
|
| 68 |
+
is ``"sliding_attention"``. When ``None``, all layers use full attention.
|
| 69 |
+
layer_types (`list[str]`, *optional*):
|
| 70 |
+
Per-layer attention type. Each element should be ``"sliding_attention"`` or
|
| 71 |
+
``"global_attention"``. Length must equal ``num_hidden_layers``. When ``None``,
|
| 72 |
+
all layers default to global attention.
|
| 73 |
+
swa_attention_sink_enabled (`bool`, *optional*, defaults to `False`):
|
| 74 |
+
Whether to enable learnable attention sinks on sliding-window attention layers.
|
| 75 |
+
num_experts (`int`, *optional*, defaults to 256):
|
| 76 |
+
Number of routed experts.
|
| 77 |
+
num_experts_per_tok (`int`, *optional*, defaults to 16):
|
| 78 |
+
Number of experts selected per token (top-k).
|
| 79 |
+
moe_intermediate_size (`int`, *optional*, defaults to 1024):
|
| 80 |
+
Intermediate size of routed experts.
|
| 81 |
+
shared_expert_intermediate_size (`int`, *optional*, defaults to 1024):
|
| 82 |
+
Intermediate size of the shared expert.
|
| 83 |
+
norm_topk_prob (`bool`, *optional*, defaults to `True`):
|
| 84 |
+
Whether to normalize top-k routing probabilities.
|
| 85 |
+
decoder_sparse_step (`int`, *optional*, defaults to 1):
|
| 86 |
+
Frequency of MoE layers (1 = every layer is MoE after mlp_only_layers).
|
| 87 |
+
mlp_only_layers (`list[int]`, *optional*, defaults to `[0]`):
|
| 88 |
+
Layer indices that use dense MLP instead of MoE.
|
| 89 |
+
router_aux_loss_coef (`float`, *optional*, defaults to 0.001):
|
| 90 |
+
Auxiliary loss coefficient for load balancing.
|
| 91 |
+
"""
|
| 92 |
+
|
| 93 |
+
model_type = "laguna"
|
| 94 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 95 |
+
base_model_tp_plan = {
|
| 96 |
+
"layers.*.self_attn.q_proj": "colwise",
|
| 97 |
+
"layers.*.self_attn.k_proj": "colwise",
|
| 98 |
+
"layers.*.self_attn.v_proj": "colwise",
|
| 99 |
+
"layers.*.self_attn.g_proj": "colwise", # Laguna-specific gating projection
|
| 100 |
+
"layers.*.self_attn.o_proj": "rowwise",
|
| 101 |
+
"layers.*.mlp.gate_proj": "colwise",
|
| 102 |
+
"layers.*.mlp.up_proj": "colwise",
|
| 103 |
+
"layers.*.mlp.down_proj": "rowwise",
|
| 104 |
+
}
|
| 105 |
+
base_model_pp_plan = {
|
| 106 |
+
"embed_tokens": (["input_ids"], ["inputs_embeds"]),
|
| 107 |
+
"layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
|
| 108 |
+
"norm": (["hidden_states"], ["hidden_states"]),
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
def __init__(
|
| 112 |
+
self,
|
| 113 |
+
vocab_size: int = 100352,
|
| 114 |
+
hidden_size: int = 2048,
|
| 115 |
+
intermediate_size: int = 8192,
|
| 116 |
+
num_hidden_layers: int = 48,
|
| 117 |
+
num_attention_heads: int = 32,
|
| 118 |
+
num_key_value_heads: int = 8,
|
| 119 |
+
head_dim: int = 128,
|
| 120 |
+
qkv_bias: bool = False,
|
| 121 |
+
attention_bias: bool = False,
|
| 122 |
+
gating: bool = True,
|
| 123 |
+
hidden_act: str = "silu",
|
| 124 |
+
max_position_embeddings: int = 4096,
|
| 125 |
+
initializer_range: float = 0.02,
|
| 126 |
+
rms_norm_eps: float = 1e-6,
|
| 127 |
+
use_cache: bool = True,
|
| 128 |
+
tie_word_embeddings: bool = False,
|
| 129 |
+
rope_theta: float = 500000.0,
|
| 130 |
+
rope_scaling: dict | None = None,
|
| 131 |
+
attention_dropout: float = 0.0,
|
| 132 |
+
sliding_window: int | None = None,
|
| 133 |
+
layer_types: list[str] | None = None,
|
| 134 |
+
swa_attention_sink_enabled: bool = False,
|
| 135 |
+
num_experts: int = 256,
|
| 136 |
+
num_experts_per_tok: int = 16,
|
| 137 |
+
moe_intermediate_size: int = 1024,
|
| 138 |
+
shared_expert_intermediate_size: int = 1024,
|
| 139 |
+
norm_topk_prob: bool = True,
|
| 140 |
+
decoder_sparse_step: int = 1,
|
| 141 |
+
mlp_only_layers: list[int] | None = None,
|
| 142 |
+
router_aux_loss_coef: float = 0.001,
|
| 143 |
+
output_router_logits: bool = False,
|
| 144 |
+
**kwargs,
|
| 145 |
+
):
|
| 146 |
+
# Default mlp_only_layers: first layer is dense (moe_first_k_dense_replace=1)
|
| 147 |
+
if mlp_only_layers is None:
|
| 148 |
+
mlp_only_layers = [0]
|
| 149 |
+
|
| 150 |
+
self.vocab_size = vocab_size
|
| 151 |
+
self.hidden_size = hidden_size
|
| 152 |
+
self.intermediate_size = intermediate_size
|
| 153 |
+
self.num_hidden_layers = num_hidden_layers
|
| 154 |
+
self.num_attention_heads = num_attention_heads
|
| 155 |
+
self.num_key_value_heads = num_key_value_heads
|
| 156 |
+
self.head_dim = head_dim
|
| 157 |
+
self.qkv_bias = qkv_bias
|
| 158 |
+
self.attention_bias = attention_bias
|
| 159 |
+
self.gating = gating
|
| 160 |
+
self.hidden_act = hidden_act
|
| 161 |
+
self.max_position_embeddings = max_position_embeddings
|
| 162 |
+
self.initializer_range = initializer_range
|
| 163 |
+
self.rms_norm_eps = rms_norm_eps
|
| 164 |
+
self.use_cache = use_cache
|
| 165 |
+
self.rope_theta = rope_theta
|
| 166 |
+
self.rope_scaling = rope_scaling
|
| 167 |
+
self.attention_dropout = attention_dropout
|
| 168 |
+
# Sliding window attention arguments
|
| 169 |
+
self.sliding_window = sliding_window
|
| 170 |
+
self.layer_types = layer_types
|
| 171 |
+
self.swa_attention_sink_enabled = swa_attention_sink_enabled
|
| 172 |
+
# MoE arguments
|
| 173 |
+
self.num_experts = num_experts
|
| 174 |
+
self.num_experts_per_tok = num_experts_per_tok
|
| 175 |
+
self.moe_intermediate_size = moe_intermediate_size
|
| 176 |
+
self.shared_expert_intermediate_size = shared_expert_intermediate_size
|
| 177 |
+
self.norm_topk_prob = norm_topk_prob
|
| 178 |
+
self.decoder_sparse_step = decoder_sparse_step
|
| 179 |
+
self.mlp_only_layers = mlp_only_layers
|
| 180 |
+
self.router_aux_loss_coef = router_aux_loss_coef
|
| 181 |
+
self.output_router_logits = output_router_logits
|
| 182 |
+
|
| 183 |
+
super().__init__(tie_word_embeddings=tie_word_embeddings, **kwargs)
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
__all__ = ["LagunaConfig"]
|
generation_config.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token_id": 2,
|
| 3 |
+
"do_sample": true,
|
| 4 |
+
"eos_token_id": [
|
| 5 |
+
2,
|
| 6 |
+
24
|
| 7 |
+
],
|
| 8 |
+
"max_new_tokens": 4096,
|
| 9 |
+
"pad_token_id": 9,
|
| 10 |
+
"temperature": 1.0,
|
| 11 |
+
"top_p": 1.0,
|
| 12 |
+
"min_p": 0.0
|
| 13 |
+
}
|
laguna.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright © 2025 Poolside AI / MLX port by Théophile Lafargue (@eauchs, x.com/eauchs)
|
| 2 |
+
#
|
| 3 |
+
# Laguna M.1 — MLX implementation
|
| 4 |
+
# Architecture: MoE (256 experts, top-16, sigmoid routing)
|
| 5 |
+
# Attention: GQA with QK-norm + softplus output gating (g_proj)
|
| 6 |
+
# RoPE: YaRN (factor=32, original_max=4096, beta_fast=64, beta_slow=1)
|
| 7 |
+
|
| 8 |
+
from dataclasses import dataclass, field
|
| 9 |
+
from typing import Any, Dict, List, Optional, Union
|
| 10 |
+
|
| 11 |
+
import mlx.core as mx
|
| 12 |
+
import mlx.nn as nn
|
| 13 |
+
|
| 14 |
+
from .base import BaseModelArgs, create_attention_mask, scaled_dot_product_attention
|
| 15 |
+
from .rope_utils import initialize_rope
|
| 16 |
+
from .switch_layers import SwitchGLU
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
@dataclass
|
| 20 |
+
class ModelArgs(BaseModelArgs):
|
| 21 |
+
model_type: str = "laguna"
|
| 22 |
+
vocab_size: int = 100352
|
| 23 |
+
hidden_size: int = 4096
|
| 24 |
+
intermediate_size: int = 16384
|
| 25 |
+
num_hidden_layers: int = 70
|
| 26 |
+
num_attention_heads: int = 64
|
| 27 |
+
num_key_value_heads: int = 8
|
| 28 |
+
head_dim: int = 128
|
| 29 |
+
max_position_embeddings: int = 131072
|
| 30 |
+
rms_norm_eps: float = 1e-6
|
| 31 |
+
rope_theta: float = 500000.0
|
| 32 |
+
rope_scaling: Optional[Dict[str, Union[float, str]]] = None
|
| 33 |
+
attention_bias: bool = False
|
| 34 |
+
attention_dropout: float = 0.0
|
| 35 |
+
tie_word_embeddings: bool = False
|
| 36 |
+
# MoE
|
| 37 |
+
num_experts: int = 256
|
| 38 |
+
num_experts_per_tok: int = 16
|
| 39 |
+
moe_intermediate_size: int = 1024
|
| 40 |
+
shared_expert_intermediate_size: int = 1024
|
| 41 |
+
norm_topk_prob: bool = True
|
| 42 |
+
moe_routed_scaling_factor: float = 1.0
|
| 43 |
+
# Layer types: "dense" or "sparse" per layer
|
| 44 |
+
mlp_layer_types: Optional[List[str]] = None
|
| 45 |
+
# Gating: "per-element" enables softplus output gating on attention
|
| 46 |
+
gating: Optional[str] = "per-element"
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class LagunaAttention(nn.Module):
|
| 50 |
+
"""Laguna attention: GQA + QK-norm + softplus output gating."""
|
| 51 |
+
|
| 52 |
+
def __init__(self, args: ModelArgs):
|
| 53 |
+
super().__init__()
|
| 54 |
+
dim = args.hidden_size
|
| 55 |
+
self.n_heads = args.num_attention_heads
|
| 56 |
+
self.n_kv_heads = args.num_key_value_heads
|
| 57 |
+
self.head_dim = args.head_dim
|
| 58 |
+
self.scale = self.head_dim ** -0.5
|
| 59 |
+
|
| 60 |
+
self.q_proj = nn.Linear(dim, self.n_heads * self.head_dim, bias=False)
|
| 61 |
+
self.k_proj = nn.Linear(dim, self.n_kv_heads * self.head_dim, bias=False)
|
| 62 |
+
self.v_proj = nn.Linear(dim, self.n_kv_heads * self.head_dim, bias=False)
|
| 63 |
+
self.o_proj = nn.Linear(self.n_heads * self.head_dim, dim, bias=False)
|
| 64 |
+
|
| 65 |
+
# Laguna-specific: output gating projection
|
| 66 |
+
self.g_proj = nn.Linear(dim, self.n_heads * self.head_dim, bias=False)
|
| 67 |
+
|
| 68 |
+
# QK normalization (per-head RMSNorm before RoPE)
|
| 69 |
+
self.q_norm = nn.RMSNorm(self.head_dim, eps=args.rms_norm_eps)
|
| 70 |
+
self.k_norm = nn.RMSNorm(self.head_dim, eps=args.rms_norm_eps)
|
| 71 |
+
|
| 72 |
+
self.rope = initialize_rope(
|
| 73 |
+
dims=self.head_dim,
|
| 74 |
+
base=args.rope_theta,
|
| 75 |
+
traditional=False,
|
| 76 |
+
max_position_embeddings=args.max_position_embeddings,
|
| 77 |
+
scaling_config=args.rope_scaling,
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
def __call__(
|
| 81 |
+
self,
|
| 82 |
+
x: mx.array,
|
| 83 |
+
mask: Optional[mx.array] = None,
|
| 84 |
+
cache: Optional[Any] = None,
|
| 85 |
+
) -> mx.array:
|
| 86 |
+
B, L, D = x.shape
|
| 87 |
+
|
| 88 |
+
queries = self.q_proj(x)
|
| 89 |
+
keys = self.k_proj(x)
|
| 90 |
+
values = self.v_proj(x)
|
| 91 |
+
|
| 92 |
+
# Reshape to [B, n_heads, L, head_dim]
|
| 93 |
+
queries = self.q_norm(
|
| 94 |
+
queries.reshape(B, L, self.n_heads, -1)
|
| 95 |
+
).transpose(0, 2, 1, 3)
|
| 96 |
+
keys = self.k_norm(
|
| 97 |
+
keys.reshape(B, L, self.n_kv_heads, -1)
|
| 98 |
+
).transpose(0, 2, 1, 3)
|
| 99 |
+
values = values.reshape(B, L, self.n_kv_heads, -1).transpose(0, 2, 1, 3)
|
| 100 |
+
|
| 101 |
+
# RoPE
|
| 102 |
+
if cache is not None:
|
| 103 |
+
queries = self.rope(queries, offset=cache.offset)
|
| 104 |
+
keys = self.rope(keys, offset=cache.offset)
|
| 105 |
+
keys, values = cache.update_and_fetch(keys, values)
|
| 106 |
+
else:
|
| 107 |
+
queries = self.rope(queries)
|
| 108 |
+
keys = self.rope(keys)
|
| 109 |
+
|
| 110 |
+
# Attention
|
| 111 |
+
output = scaled_dot_product_attention(
|
| 112 |
+
queries, keys, values, cache=cache, scale=self.scale, mask=mask
|
| 113 |
+
)
|
| 114 |
+
output = output.transpose(0, 2, 1, 3).reshape(B, L, -1)
|
| 115 |
+
|
| 116 |
+
# Laguna-specific: softplus gating BEFORE o_proj
|
| 117 |
+
gate = nn.softplus(self.g_proj(x))
|
| 118 |
+
output = output * gate
|
| 119 |
+
|
| 120 |
+
return self.o_proj(output)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
class LagunaMLP(nn.Module):
|
| 124 |
+
def __init__(self, dim: int, hidden_dim: int):
|
| 125 |
+
super().__init__()
|
| 126 |
+
self.gate_proj = nn.Linear(dim, hidden_dim, bias=False)
|
| 127 |
+
self.up_proj = nn.Linear(dim, hidden_dim, bias=False)
|
| 128 |
+
self.down_proj = nn.Linear(hidden_dim, dim, bias=False)
|
| 129 |
+
|
| 130 |
+
def __call__(self, x: mx.array) -> mx.array:
|
| 131 |
+
return self.down_proj(nn.silu(self.gate_proj(x)) * self.up_proj(x))
|
| 132 |
+
|
| 133 |
+
|
| 134 |
+
class LagunaRouter(nn.Module):
|
| 135 |
+
"""Sigmoid-based top-k router (not softmax)."""
|
| 136 |
+
|
| 137 |
+
def __init__(self, args: ModelArgs):
|
| 138 |
+
super().__init__()
|
| 139 |
+
self.top_k = args.num_experts_per_tok
|
| 140 |
+
self.num_experts = args.num_experts
|
| 141 |
+
self.norm_topk_prob = args.norm_topk_prob
|
| 142 |
+
self.weight = mx.zeros((self.num_experts, args.hidden_size))
|
| 143 |
+
self.e_score_correction_bias = mx.zeros((self.num_experts,))
|
| 144 |
+
|
| 145 |
+
def __call__(self, x: mx.array):
|
| 146 |
+
# Sigmoid scoring in float32 for precision
|
| 147 |
+
router_logits = x @ self.weight.T
|
| 148 |
+
scores = mx.sigmoid(router_logits.astype(mx.float32))
|
| 149 |
+
|
| 150 |
+
# Apply correction bias for expert selection (not for final weights)
|
| 151 |
+
corrected_scores = scores + self.e_score_correction_bias
|
| 152 |
+
|
| 153 |
+
# Top-k selection on corrected scores
|
| 154 |
+
k = self.top_k
|
| 155 |
+
inds = mx.argpartition(-corrected_scores, kth=k - 1, axis=-1)[..., :k]
|
| 156 |
+
# Use original scores (without bias) for weighting
|
| 157 |
+
routing_weights = mx.take_along_axis(scores, inds, axis=-1)
|
| 158 |
+
|
| 159 |
+
if self.norm_topk_prob:
|
| 160 |
+
routing_weights = routing_weights / mx.sum(
|
| 161 |
+
routing_weights, axis=-1, keepdims=True
|
| 162 |
+
)
|
| 163 |
+
|
| 164 |
+
return inds, routing_weights.astype(x.dtype)
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
class LagunaSparseMoeBlock(nn.Module):
|
| 168 |
+
"""Laguna MoE: sigmoid router + SwitchGLU experts + shared expert."""
|
| 169 |
+
|
| 170 |
+
def __init__(self, args: ModelArgs):
|
| 171 |
+
super().__init__()
|
| 172 |
+
self.gate = LagunaRouter(args)
|
| 173 |
+
self.switch_mlp = SwitchGLU(
|
| 174 |
+
args.hidden_size,
|
| 175 |
+
args.moe_intermediate_size,
|
| 176 |
+
args.num_experts,
|
| 177 |
+
)
|
| 178 |
+
self.shared_expert = LagunaMLP(
|
| 179 |
+
args.hidden_size, args.shared_expert_intermediate_size
|
| 180 |
+
)
|
| 181 |
+
|
| 182 |
+
def __call__(self, x: mx.array) -> mx.array:
|
| 183 |
+
inds, scores = self.gate(x)
|
| 184 |
+
|
| 185 |
+
# Routed experts via SwitchGLU
|
| 186 |
+
y = self.switch_mlp(x, inds)
|
| 187 |
+
y = (y * scores[..., None]).sum(axis=-2).astype(y.dtype)
|
| 188 |
+
|
| 189 |
+
# Add shared expert
|
| 190 |
+
y = y + self.shared_expert(x)
|
| 191 |
+
|
| 192 |
+
return y
|
| 193 |
+
|
| 194 |
+
|
| 195 |
+
class LagunaDecoderLayer(nn.Module):
|
| 196 |
+
def __init__(self, args: ModelArgs, layer_idx: int):
|
| 197 |
+
super().__init__()
|
| 198 |
+
self.self_attn = LagunaAttention(args)
|
| 199 |
+
self.input_layernorm = nn.RMSNorm(args.hidden_size, eps=args.rms_norm_eps)
|
| 200 |
+
self.post_attention_layernorm = nn.RMSNorm(
|
| 201 |
+
args.hidden_size, eps=args.rms_norm_eps
|
| 202 |
+
)
|
| 203 |
+
|
| 204 |
+
# Dense or sparse MLP based on mlp_layer_types
|
| 205 |
+
is_sparse = (
|
| 206 |
+
args.mlp_layer_types is not None
|
| 207 |
+
and layer_idx < len(args.mlp_layer_types)
|
| 208 |
+
and args.mlp_layer_types[layer_idx] == "sparse"
|
| 209 |
+
)
|
| 210 |
+
if is_sparse:
|
| 211 |
+
self.mlp = LagunaSparseMoeBlock(args)
|
| 212 |
+
else:
|
| 213 |
+
self.mlp = LagunaMLP(args.hidden_size, args.intermediate_size)
|
| 214 |
+
|
| 215 |
+
def __call__(
|
| 216 |
+
self,
|
| 217 |
+
x: mx.array,
|
| 218 |
+
mask: Optional[mx.array] = None,
|
| 219 |
+
cache: Optional[Any] = None,
|
| 220 |
+
) -> mx.array:
|
| 221 |
+
r = self.self_attn(self.input_layernorm(x), mask, cache)
|
| 222 |
+
h = x + r
|
| 223 |
+
r = self.mlp(self.post_attention_layernorm(h))
|
| 224 |
+
return h + r
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
class LagunaModel(nn.Module):
|
| 228 |
+
def __init__(self, args: ModelArgs):
|
| 229 |
+
super().__init__()
|
| 230 |
+
self.embed_tokens = nn.Embedding(args.vocab_size, args.hidden_size)
|
| 231 |
+
self.layers = [
|
| 232 |
+
LagunaDecoderLayer(args, i) for i in range(args.num_hidden_layers)
|
| 233 |
+
]
|
| 234 |
+
self.norm = nn.RMSNorm(args.hidden_size, eps=args.rms_norm_eps)
|
| 235 |
+
|
| 236 |
+
def __call__(
|
| 237 |
+
self,
|
| 238 |
+
inputs: mx.array,
|
| 239 |
+
cache=None,
|
| 240 |
+
) -> mx.array:
|
| 241 |
+
h = self.embed_tokens(inputs)
|
| 242 |
+
|
| 243 |
+
if cache is None:
|
| 244 |
+
cache = [None] * len(self.layers)
|
| 245 |
+
|
| 246 |
+
mask = create_attention_mask(h, cache[0])
|
| 247 |
+
|
| 248 |
+
for layer, c in zip(self.layers, cache):
|
| 249 |
+
h = layer(h, mask, c)
|
| 250 |
+
|
| 251 |
+
return self.norm(h)
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
class Model(nn.Module):
|
| 255 |
+
def __init__(self, args: ModelArgs):
|
| 256 |
+
super().__init__()
|
| 257 |
+
self.args = args
|
| 258 |
+
self.model_type = args.model_type
|
| 259 |
+
self.model = LagunaModel(args)
|
| 260 |
+
if not args.tie_word_embeddings:
|
| 261 |
+
self.lm_head = nn.Linear(args.hidden_size, args.vocab_size, bias=False)
|
| 262 |
+
|
| 263 |
+
def __call__(
|
| 264 |
+
self,
|
| 265 |
+
inputs: mx.array,
|
| 266 |
+
cache=None,
|
| 267 |
+
):
|
| 268 |
+
out = self.model(inputs, cache)
|
| 269 |
+
if self.args.tie_word_embeddings:
|
| 270 |
+
return self.model.embed_tokens.as_linear(out)
|
| 271 |
+
return self.lm_head(out)
|
| 272 |
+
|
| 273 |
+
def sanitize(self, weights):
|
| 274 |
+
# Dequantize FP8 compressed-tensors: uint8 + weight_scale → bfloat16
|
| 275 |
+
new_weights = {}
|
| 276 |
+
for k, v in weights.items():
|
| 277 |
+
if k.endswith("weight_scale"):
|
| 278 |
+
continue # handled with corresponding weight
|
| 279 |
+
if k.endswith(".weight") and f"{k}_scale" in weights:
|
| 280 |
+
scale = weights[f"{k}_scale"]
|
| 281 |
+
new_weights[k] = self._dequant_fp8_block(v, scale)
|
| 282 |
+
else:
|
| 283 |
+
new_weights[k] = v
|
| 284 |
+
weights = new_weights
|
| 285 |
+
|
| 286 |
+
# Remap e_score_correction_bias:
|
| 287 |
+
# HF: model.layers.X.mlp.experts.e_score_correction_bias
|
| 288 |
+
# MLX: model.layers.X.mlp.gate.e_score_correction_bias
|
| 289 |
+
remapped = {}
|
| 290 |
+
for k, v in weights.items():
|
| 291 |
+
if "mlp.experts.e_score_correction_bias" in k:
|
| 292 |
+
new_key = k.replace(
|
| 293 |
+
"mlp.experts.e_score_correction_bias",
|
| 294 |
+
"mlp.gate.e_score_correction_bias",
|
| 295 |
+
)
|
| 296 |
+
remapped[new_key] = v
|
| 297 |
+
else:
|
| 298 |
+
remapped[k] = v
|
| 299 |
+
weights = remapped
|
| 300 |
+
|
| 301 |
+
# Stack per-expert weights into SwitchGLU format
|
| 302 |
+
for l in range(self.args.num_hidden_layers):
|
| 303 |
+
prefix = f"model.layers.{l}"
|
| 304 |
+
for n in ["up_proj", "down_proj", "gate_proj"]:
|
| 305 |
+
key0 = f"{prefix}.mlp.experts.0.{n}.weight"
|
| 306 |
+
if key0 in weights:
|
| 307 |
+
to_join = [
|
| 308 |
+
weights.pop(f"{prefix}.mlp.experts.{e}.{n}.weight")
|
| 309 |
+
for e in range(self.args.num_experts)
|
| 310 |
+
]
|
| 311 |
+
weights[f"{prefix}.mlp.switch_mlp.{n}.weight"] = mx.stack(
|
| 312 |
+
to_join
|
| 313 |
+
)
|
| 314 |
+
|
| 315 |
+
# Remove unused keys
|
| 316 |
+
weights = {
|
| 317 |
+
k: v
|
| 318 |
+
for k, v in weights.items()
|
| 319 |
+
if "rotary_emb.inv_freq" not in k
|
| 320 |
+
}
|
| 321 |
+
|
| 322 |
+
return weights
|
| 323 |
+
|
| 324 |
+
@staticmethod
|
| 325 |
+
def _dequant_fp8_block(weight: mx.array, scale: mx.array) -> mx.array:
|
| 326 |
+
"""Dequantize FP8 block-quantized weight (uint8 + scale → bfloat16).
|
| 327 |
+
|
| 328 |
+
Block size is 128x128 (inferred from scale shape vs weight shape).
|
| 329 |
+
"""
|
| 330 |
+
m, n = weight.shape
|
| 331 |
+
sm, sn = scale.shape
|
| 332 |
+
bs_m = m // sm # block size along rows
|
| 333 |
+
bs_n = n // sn # block size along cols
|
| 334 |
+
|
| 335 |
+
# Reinterpret uint8 as float8 E4M3, then cast to bfloat16
|
| 336 |
+
weight_bf16 = mx.from_fp8(weight, mx.bfloat16)
|
| 337 |
+
|
| 338 |
+
# Apply block-wise scale
|
| 339 |
+
weight_bf16 = weight_bf16.reshape(sm, bs_m, sn, bs_n)
|
| 340 |
+
weight_bf16 = weight_bf16 * scale[:, None, :, None]
|
| 341 |
+
weight_bf16 = weight_bf16.reshape(m, n)
|
| 342 |
+
|
| 343 |
+
return weight_bf16
|
| 344 |
+
|
| 345 |
+
@property
|
| 346 |
+
def layers(self):
|
| 347 |
+
return self.model.layers
|
| 348 |
+
|
| 349 |
+
@property
|
| 350 |
+
def quant_predicate(self):
|
| 351 |
+
def predicate(path, _):
|
| 352 |
+
# Don't quantize router gate weights — keep full precision
|
| 353 |
+
if "mlp.gate.weight" in path:
|
| 354 |
+
return {"group_size": 64, "bits": 8}
|
| 355 |
+
return True
|
| 356 |
+
|
| 357 |
+
return predicate
|
model-00000.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:289d02fc06a716236c5574faf8299a2b57c6c35e131dd8cdcc33b318cb89081f
|
| 3 |
+
size 1644175670
|
model-00001.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6883ec5004f6a0f891892d9743eab15839dabb87219baa4cd2bf3a0278e1a88f
|
| 3 |
+
size 135810626
|
model-00002.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:67fe2b2e953b88ac2e677444bb7d98bedde977c359f72bcb2b0f1a9158db3b77
|
| 3 |
+
size 135810606
|
model-00003.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e7172422290ce2d10224789d100547342746164213a2a12eb8855fe54cd6e29f
|
| 3 |
+
size 135810598
|
model-00004.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f59123e6a5be39b3e22767acde50728331381949ceaa309f408adc578ef8e5ee
|
| 3 |
+
size 1464621066
|
model-00005.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b1249787a894391e3c8003106c7fa4412c9fef96bda364aa322c763baa5adacc
|
| 3 |
+
size 1464621118
|
model-00006.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7896e367cfcbf371fbade5332080136a67f3fbb7a48c20ed6ce175281bad3805
|
| 3 |
+
size 1464621074
|
model-00007.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c9edd2ed48a70e3f5f33e8ecdb16cd6531a7930ff56b358ecaa641152f6bef9c
|
| 3 |
+
size 1464621052
|
model-00008.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7d99308fee141b7dec27bcfe9ccb8e0b464ad28e567f6eb3864963e9c50a092c
|
| 3 |
+
size 1464621064
|
model-00009.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1de2f6b54f7d28bc23db7294870e8241e6ba1a5becddf87c3f87ccf4aa526591
|
| 3 |
+
size 1464621064
|
model-00010.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dfcf2f8a7c8bee7a00c25b06c6a27264237dc348be585bf488f7ea14c2d743b4
|
| 3 |
+
size 1464621072
|
model-00011.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:43fddd5e9a40e7c55fd409edb407500dc15c8405dfc5205b9479247ffb6b00e0
|
| 3 |
+
size 1464621115
|
model-00012.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1fea6040cdcfcc3c3f1aaac94fedf55c958e4ed21abda9af6cb8f631b43396d0
|
| 3 |
+
size 1464621113
|
model-00013.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7495e941f0617de41038b69afc0f3b45debc8abd28d6fec0ae0c2a0244bc25ab
|
| 3 |
+
size 1464621115
|
model-00014.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f9eaa0c634656292f68eda91232860071898f4bf3fa2458a13997fc00e74cfc3
|
| 3 |
+
size 1464621147
|
model-00015.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:aaac5d0d89dd4912a2656719ad408259f0514a7e127c60fe90b8cb88b0ca400f
|
| 3 |
+
size 1464621119
|
model-00016.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5c20a269e34555331131e1d7314689f121cd39f8086d89dce73f080b285338ce
|
| 3 |
+
size 1464621099
|
model-00017.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:777721efce68f71f4c9b92d8aaab9e4c42f9cda4bfa2ef232cd8e14aa688c94e
|
| 3 |
+
size 1464621151
|
model-00018.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cf6944fd2bbe141b7acf70bf66764d251b32de1d936d72bc49a357197d57bb0f
|
| 3 |
+
size 1464621127
|
model-00019.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7084ee3642b757eeb6ad376863c54c5df086c35c5ec88329a3affc11d4c1f86c
|
| 3 |
+
size 1464621111
|
model-00020.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:364cc3f94ac63ee413ec9756f73358f8a3c065f2d411d555ad39eb92a4f1d9b6
|
| 3 |
+
size 1464621131
|
model-00021.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b90c7a8cf19dc5b816e5c318480db5b17ea7a34361ae8cc82a8cafdb956edc3f
|
| 3 |
+
size 1464621139
|
model-00022.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c1b86cfdc1b8d8959fbae7718a65f218bacf89839ad2e5073f4fa8bb0ee49e40
|
| 3 |
+
size 1464621099
|
model-00023.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ce85a6ddc63df580dd08e3fba629140e8b7e3f644894ba7593de2b42cb768a59
|
| 3 |
+
size 1464621101
|
model-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:af66c4dfaeb860604f8eee4fea2d72aaa2a71e2a3fc54641dd42d489ff380e32
|
| 3 |
+
size 1464621115
|
model-00025.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:943998d5af4c439940888bc0b3ddccd24922f953d4de70833054aca993323cd6
|
| 3 |
+
size 1464621123
|
model-00026.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a5da51efb166cb877fbd0a0427726baa266dca616f67d6acbe996f1a874b4a68
|
| 3 |
+
size 1464621149
|
model-00027.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a1e66e74fedb60fbef11c57620030b800a7faab81f77e15895e1ebb21115b4e1
|
| 3 |
+
size 1464621125
|
model-00028.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:900189d65c3cbe5b0d21c881717c238fef028650e9d97c86ce6558f457575e90
|
| 3 |
+
size 1464621129
|
model-00029.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ad3e5586b16a345c02887d661c072b38c18c03a64fe0affe93f93ea9e257fff6
|
| 3 |
+
size 1464621105
|
model-00030.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e635491b95e8171efb622c08d1bf874f42a65c5c7e30907245f8b81e27d1ae43
|
| 3 |
+
size 1464621121
|
model-00031.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:79c104139be06236652966fd043c89c27e33977ec7a3eb7dc6d9fb45271ad23e
|
| 3 |
+
size 1464621097
|
model-00032.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1b206c21e5fcda44424fcd98132e5f1e2209269d120c69ee126ebf18d101549b
|
| 3 |
+
size 1464621121
|
model-00033.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7eb82761a82a1c91c2d8c96b49f428a314c504dc94c42c131c3cbefd4bd07113
|
| 3 |
+
size 1464621117
|
model-00034.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2e379d82236fcead29d1c1bb57d7f2b9e32705b512577af812fa8636ea978e77
|
| 3 |
+
size 1464621099
|
model-00035.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:bdcdd537fd1f3ca4f6dcbbe152d0492ff6004ac50998518064ab5e521b7ec2be
|
| 3 |
+
size 1464621109
|
model-00036.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5a675b978c670dd93f7b3fc7c6c028d5c8ae6b4c0917e787d5fd5812e587ceea
|
| 3 |
+
size 1464621147
|
model-00037.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8878d9a2538e1957863b141d850cc5d490ea2848ab9a0a1ffbd53eac96e5bb56
|
| 3 |
+
size 1464621105
|
model-00038.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e403b45c3e106108a15f0bf1bdadb35a7f1e1da34dc99daffb03dcbd8c3c8cdc
|
| 3 |
+
size 1464621095
|
model-00039.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cf0fa1750fc082162fed306a88689f601e2c4785afcf91ecec92c51a41c25c6d
|
| 3 |
+
size 1464621097
|
model-00040.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d61d869ae3c6c095af4397b186bf9b233b3a945a8f2b3b29a4e9e96943215cf8
|
| 3 |
+
size 1464621141
|
model-00041.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:70c255f87050008a1e722201c12c20f707ff9d7b40fc33519d72ec4feb23eee5
|
| 3 |
+
size 1464621093
|
model-00042.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:150ec5af9a70cf8d53c87ec8262c158c457191a19a4b070878c6c0f7ed6a2b9a
|
| 3 |
+
size 1464621105
|