Text Generation
Transformers
Safetensors
bailing_hybrid
Mixture of Experts
nvfp4
compressed-tensors
quantized
vllm
hybrid-linear-attention
conversational
custom_code
8-bit precision
Instructions to use olka-fi/Ling-3.0-flash-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use olka-fi/Ling-3.0-flash-NVFP4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="olka-fi/Ling-3.0-flash-NVFP4", trust_remote_code=True) messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModelForCausalLM model = AutoModelForCausalLM.from_pretrained("olka-fi/Ling-3.0-flash-NVFP4", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use olka-fi/Ling-3.0-flash-NVFP4 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "olka-fi/Ling-3.0-flash-NVFP4" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "olka-fi/Ling-3.0-flash-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/olka-fi/Ling-3.0-flash-NVFP4
- SGLang
How to use olka-fi/Ling-3.0-flash-NVFP4 with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "olka-fi/Ling-3.0-flash-NVFP4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "olka-fi/Ling-3.0-flash-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "olka-fi/Ling-3.0-flash-NVFP4" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "olka-fi/Ling-3.0-flash-NVFP4", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use olka-fi/Ling-3.0-flash-NVFP4 with Docker Model Runner:
docker model run hf.co/olka-fi/Ling-3.0-flash-NVFP4
NVFP4 (weight-only, mixed precision) quantization of inclusionAI/Ling-3.0-flash via qstream
Browse files- .gitattributes +2 -0
- README.md +368 -0
- chat_template.jinja +130 -0
- config.json +213 -0
- configuration_bailing_moe_v3.py +126 -0
- model-00001-of-00024.safetensors +3 -0
- model-00002-of-00024.safetensors +3 -0
- model-00003-of-00024.safetensors +3 -0
- model-00004-of-00024.safetensors +3 -0
- model-00005-of-00024.safetensors +3 -0
- model-00006-of-00024.safetensors +3 -0
- model-00007-of-00024.safetensors +3 -0
- model-00008-of-00024.safetensors +3 -0
- model-00009-of-00024.safetensors +3 -0
- model-00010-of-00024.safetensors +3 -0
- model-00011-of-00024.safetensors +3 -0
- model-00012-of-00024.safetensors +3 -0
- model-00013-of-00024.safetensors +3 -0
- model-00014-of-00024.safetensors +3 -0
- model-00015-of-00024.safetensors +3 -0
- model-00016-of-00024.safetensors +3 -0
- model-00017-of-00024.safetensors +3 -0
- model-00018-of-00024.safetensors +3 -0
- model-00019-of-00024.safetensors +3 -0
- model-00020-of-00024.safetensors +3 -0
- model-00021-of-00024.safetensors +3 -0
- model-00022-of-00024.safetensors +3 -0
- model-00023-of-00024.safetensors +3 -0
- model-00024-of-00024.safetensors +3 -0
- model.safetensors.index.json +3 -0
- modeling_bailing_moe_v3.py +1625 -0
- special_tokens_map.json +30 -0
- tokenizer.json +3 -0
- tokenizer_config.json +2113 -0
- vllm_patch/README.md +63 -0
- vllm_patch/compressed_tensors_moe_w4a4_mxfp4.py +240 -0
- vllm_patch/config.py +1462 -0
- vllm_patch/cutlass_moe.py +1441 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ 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
|
| 37 |
+
model.safetensors.index.json filter=lfs diff=lfs merge=lfs -text
|
README.md
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
pipeline_tag: text-generation
|
| 4 |
+
library_name: transformers
|
| 5 |
+
base_model: inclusionAI/Ling-3.0-flash
|
| 6 |
+
base_model_relation: quantized
|
| 7 |
+
tags:
|
| 8 |
+
- moe
|
| 9 |
+
- nvfp4
|
| 10 |
+
- compressed-tensors
|
| 11 |
+
- quantized
|
| 12 |
+
- vllm
|
| 13 |
+
- hybrid-linear-attention
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# Ling-3.0-flash — NVFP4 (weight-only, mixed precision)
|
| 17 |
+
|
| 18 |
+
A 4-bit **NVFP4** quantization of [Ling-3.0-flash](https://huggingface.co/inclusionAI/Ling-3.0-flash),
|
| 19 |
+
produced with [**qstream**](https://github.com/olka/qstream). The routed MoE experts
|
| 20 |
+
(~95% of the weights) are quantized to NVFP4; everything quality-sensitive stays **BF16**.
|
| 21 |
+
|
| 22 |
+
**The original model card follows in full [below](#original-model-card).**
|
| 23 |
+
|
| 24 |
+
> ### ⚠️ Speculative decoding (MTP) is broken on this checkpoint — do not enable it
|
| 25 |
+
>
|
| 26 |
+
> Measured **0% acceptance across 89,832 draft tokens** (29,944 draft steps, zero accepted
|
| 27 |
+
> at every draft position). MTP is not merely inefficient here, it contributes nothing
|
| 28 |
+
> while costing a redundant full-checkpoint read at startup, ~6 GB of VRAM for the BF16
|
| 29 |
+
> MTP head, and three wasted draft forwards per decode step. It additionally crashes CUDA
|
| 30 |
+
> graph capture (`gdn_attn.py` → `CUDA error: invalid argument`), forcing `--enforce-eager`
|
| 31 |
+
> and giving up decode throughput.
|
| 32 |
+
>
|
| 33 |
+
> **Serve without `--speculative-config`.** Without a draft model, graph capture succeeds
|
| 34 |
+
> and everything behaves normally. The MTP layer is still shipped at BF16 so the head is
|
| 35 |
+
> intact for whenever the runtime issue is fixed upstream. See
|
| 36 |
+
> [Known issues](#known-issues).
|
| 37 |
+
|
| 38 |
+
| | |
|
| 39 |
+
|---|---|
|
| 40 |
+
| **Size** | **81.4 GB** (down from 255.0 GB BF16 source, ~32%) |
|
| 41 |
+
| **Format** | compressed-tensors `nvfp4-pack-quantized` (E2M1 4-bit + FP8-E4M3 group-16 scales + per-tensor global scale) |
|
| 42 |
+
| **Base** | Ling-3.0-flash — 124B total / 5.1B active hybrid-linear MoE; 42 layers stacked 5:1 as 35 Kimi-Delta-Attention (KDA) + 7 gated-MLA; 512 routed experts top-8 + 1 shared; 2 dense layers; 1 MTP layer; 256K context |
|
| 43 |
+
|
| 44 |
+
## Which build should you use?
|
| 45 |
+
|
| 46 |
+
**Most people should take the [MXFP4 build](https://huggingface.co/olka-fi/Ling-3.0-flash-MXFP4) instead.**
|
| 47 |
+
NVFP4 reconstructs the weights substantially more faithfully, and that advantage does not
|
| 48 |
+
show up downstream:
|
| 49 |
+
|
| 50 |
+
| | [MXFP4](https://huggingface.co/olka-fi/Ling-3.0-flash-MXFP4) | NVFP4 (this repo) |
|
| 51 |
+
|---|---|---|
|
| 52 |
+
| Size | **77.6 GB** | 81.4 GB |
|
| 53 |
+
| Median weight rel. error | 0.111618 | **0.086498** (−22.5%) |
|
| 54 |
+
| GSM8K 5-shot, full 1319, flexible-extract | **84.38%** ±1.00 | 83.17% ±1.03 |
|
| 55 |
+
| GSM8K 5-shot, full 1319, strict-match | **78.85%** ±1.12 | 78.39% ±1.13 |
|
| 56 |
+
|
| 57 |
+
Both GSM8K gaps are under 1.2σ — the two builds are statistically indistinguishable on
|
| 58 |
+
this benchmark despite NVFP4's much lower weight error. At this magnitude, 4-bit
|
| 59 |
+
reconstruction error is already below what GSM8K can resolve. NVFP4 is published for
|
| 60 |
+
comparison and for anyone wanting the more faithful weights (e.g. for longer-generation
|
| 61 |
+
or harder tasks where the difference may still surface); MXFP4 is the smaller, better-
|
| 62 |
+
tested release.
|
| 63 |
+
|
| 64 |
+
## What is quantized to what
|
| 65 |
+
|
| 66 |
+
| Component | Precision | Why |
|
| 67 |
+
|---|---|---|
|
| 68 |
+
| Routed experts, layers 2–41 (`model.layers.N.mlp.experts.E.{gate,up,down}_proj`) | **NVFP4** (4-bit) | 120.8B of 127.4B params — the only place worth the size win |
|
| 69 |
+
| Shared expert (`mlp.shared_experts.*`) | **BF16** | active on *every* token; quantizing it costs ~half the quality loss for <1% of the size |
|
| 70 |
+
| Attention — KDA (`q/k/v/f/g/b_proj`, `conv1d`, `A_log`, `dt_bias`) and gated MLA (`kv_a/kv_b`, `dense`) | **BF16** | the KDA gating projections feed a softplus/sigmoid decay gate and are the most precision-sensitive tensors in the model |
|
| 71 |
+
| Router gate + `expert_bias`, dense MLP (layers 0–1) | **BF16** | routing decisions are discrete; a perturbed router changes *which* experts fire |
|
| 72 |
+
| MTP layer 42 (incl. its own 512 experts) | **BF16** | speculative-decoding draft path — see the MTP warning above |
|
| 73 |
+
| Embeddings, `lm_head`, all norms | **BF16** | unchanged |
|
| 74 |
+
|
| 75 |
+
61,440 tensors quantized (40 layers × 512 experts × 3 projections), each with a packed
|
| 76 |
+
weight, an FP8-E4M3 group scale and a per-tensor global scale.
|
| 77 |
+
|
| 78 |
+
## Fidelity
|
| 79 |
+
|
| 80 |
+
Weight-reconstruction relative error, 960-tensor stratified sample (24 per layer, expert
|
| 81 |
+
ids strided across the full 512 range, all 40 layers):
|
| 82 |
+
|
| 83 |
+
| min | p25 | median | p75 | p95 | max | std |
|
| 84 |
+
|---|---|---|---|---|---|---|
|
| 85 |
+
| 0.086332 | 0.086459 | **0.086498** | 0.086556 | 0.086652 | 0.086742 | 0.000073 |
|
| 86 |
+
|
| 87 |
+
NVFP4's *worst* sampled tensor (0.0867) is better than MXFP4's *best* (0.1099) — the two
|
| 88 |
+
distributions are disjoint. Two effects compound: group 16 rather than 32 halves how many
|
| 89 |
+
weights share a scale, and FP8-E4M3 scales are continuous where MXFP4's E8M0 scales are
|
| 90 |
+
powers of two, so an MXFP4 block whose ideal scale falls between 2^k and 2^(k+1) must
|
| 91 |
+
round and waste up to 2× of range.
|
| 92 |
+
|
| 93 |
+
## Known issues
|
| 94 |
+
|
| 95 |
+
1. **MTP / speculative decoding: 0% acceptance** — see the warning above. Serve without
|
| 96 |
+
`--speculative-config`.
|
| 97 |
+
2. **MTP also breaks CUDA graph capture** (`gdn_attn.py:382` → `CUDA error: invalid
|
| 98 |
+
argument`). Without a draft model, capture succeeds and `--enforce-eager` is not needed.
|
| 99 |
+
3. **The MTP draft loader re-reads the entire checkpoint** to extract one layer — two
|
| 100 |
+
full weight-loading passes of near-identical duration at startup. Costs I/O, not VRAM.
|
| 101 |
+
4. **NVFP4 needs qstream ≥ the `_prune_ignore` fix.** Earlier qstream generalised `ignore`
|
| 102 |
+
entries by layer index, so excluding the MTP layer emitted
|
| 103 |
+
`re:.*layers\.\d+\.mlp\.experts\.\d+\.gate_proj$` — which also ignored the *quantized*
|
| 104 |
+
experts in all 40 other layers. vLLM checks `should_ignore_layer` before target
|
| 105 |
+
matching, so every expert silently resolved to unquantized and the loader tried to
|
| 106 |
+
allocate BF16 buffers for ~242 GB of weights (OOM with no useful error). The
|
| 107 |
+
`config.json` in this repo is already correct.
|
| 108 |
+
|
| 109 |
+
## Serving with vLLM
|
| 110 |
+
|
| 111 |
+
Ling-3.0 (`BailingMoeV3ForCausalLM`, `model_type: bailing_hybrid`) needs the vendor fork
|
| 112 |
+
**[`inclusionAI/vllm`](https://github.com/inclusionAI/vllm), branch `ling_3_0`**. (The base
|
| 113 |
+
model card points at `inclusionAI/vllm-ling-v3`, which does not exist.) Upstream vLLM has
|
| 114 |
+
only BailingMoe / V2 / V2.5.
|
| 115 |
+
|
| 116 |
+
### Required: the MoE clamp patch
|
| 117 |
+
|
| 118 |
+
Ling-3.0 declares a **per-layer clamped SwiGLU** (`expert_swiglu_limit_list = [0]*35 + [4]*7`,
|
| 119 |
+
so layers 35–41 clamp at 4). vLLM's compressed-tensors MXFP4/NVFP4 MoE path **drops that
|
| 120 |
+
clamp**: the quant method never reads `layer.swiglu_limit`, the quant-config builder has no
|
| 121 |
+
parameter to receive it, and `run_cutlass_moe_mxfp4` calls `apply_moe_activation()` with no
|
| 122 |
+
clamp argument. The result is unclamped SwiGLU on layers 35–41 — the divergence is large,
|
| 123 |
+
not marginal (gate=10 gives `silu(10)*2 = 20.0` versus `silu(4)*2 = 7.84`).
|
| 124 |
+
|
| 125 |
+
Apply the three files in [`vllm_patch/`](./vllm_patch/) over the fork before serving; they
|
| 126 |
+
are pure Python, so an editable install needs no rebuild. See
|
| 127 |
+
[`vllm_patch/README.md`](./vllm_patch/README.md).
|
| 128 |
+
|
| 129 |
+
### Launch (Docker)
|
| 130 |
+
|
| 131 |
+
A prebuilt runtime image with the fork, the clamp patch and `flashinfer-jit-cache`:
|
| 132 |
+
|
| 133 |
+
```bash
|
| 134 |
+
docker run --gpus all -d --name ling3 --ipc=host -p 8000:8000 \
|
| 135 |
+
-v /path/to/Ling-3.0-flash-NVFP4:/models/Ling-3.0-flash-NVFP4:ro \
|
| 136 |
+
olkafi/vllm-bailing-v3:latest \
|
| 137 |
+
/models/Ling-3.0-flash-NVFP4 \
|
| 138 |
+
--served-model-name ling3 --trust-remote-code \
|
| 139 |
+
--host 0.0.0.0 --port 8000 \
|
| 140 |
+
--gpu-memory-utilization 0.85 --max-model-len 32768 \
|
| 141 |
+
--enable-prefix-caching --mamba-cache-mode align \
|
| 142 |
+
--load-format fastsafetensors \
|
| 143 |
+
--enable-auto-tool-choice --tool-call-parser ling3 --reasoning-parser ling3
|
| 144 |
+
```
|
| 145 |
+
|
| 146 |
+
`--enable-prefix-caching` is **required** for `--mamba-cache-mode align` to take effect —
|
| 147 |
+
without it vLLM silently downgrades the KDA linear-attention state cache to `none` and
|
| 148 |
+
only logs a warning. Note the deliberate absence of `--speculative-config`.
|
| 149 |
+
|
| 150 |
+
Recommended sampling (from the base card): `temperature=0.6`, `top_p=0.95`, `top_k=20`,
|
| 151 |
+
with `enable_thinking`.
|
| 152 |
+
|
| 153 |
+
## Provenance
|
| 154 |
+
|
| 155 |
+
Built with [qstream](https://github.com/olka/qstream) from the BF16
|
| 156 |
+
`inclusionAI/Ling-3.0-flash` release:
|
| 157 |
+
|
| 158 |
+
```bash
|
| 159 |
+
qstream-quantize \
|
| 160 |
+
--model_dir Ling-3.0-flash \
|
| 161 |
+
--output_dir Ling-3.0-flash-NVFP4 \
|
| 162 |
+
--quant_format nvfp4 --nvfp4_mse --format ct \
|
| 163 |
+
--include_layers '*.mlp.experts.*' \
|
| 164 |
+
--exclude_layers '*.layers.42.*' \
|
| 165 |
+
--workers 8 --device cuda
|
| 166 |
+
```
|
| 167 |
+
|
| 168 |
+
`--nvfp4_mse` searches neighbouring E4M3 group scales and keeps the minimum-reconstruction-
|
| 169 |
+
error one, with γ-weighted activation awareness from `post_attention_layernorm`.
|
| 170 |
+
|
| 171 |
+
## Evaluation notes
|
| 172 |
+
|
| 173 |
+
GSM8K figures above are 5-shot over the full 1319-problem test set via `/v1/completions`
|
| 174 |
+
with plain few-shot prompting — a **non-thinking** protocol. They are not comparable to the
|
| 175 |
+
base model's published scores, which are generated with thinking mode + CoT. They exist to
|
| 176 |
+
bound quantization damage, not as leaderboard claims.
|
| 177 |
+
|
| 178 |
+
## License
|
| 179 |
+
|
| 180 |
+
Inherits the **MIT** license from the base model. This is a derivative (quantized) work of
|
| 181 |
+
inclusionAI/Ling-3.0-flash.
|
| 182 |
+
|
| 183 |
+
---
|
| 184 |
+
|
| 185 |
+
# Original model card
|
| 186 |
+
|
| 187 |
+
<p align="center">
|
| 188 |
+
<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*4QxcQrBlTiAAAAAAQXAAAAgAemJ7AQ/original" width="100"/>
|
| 189 |
+
</p>
|
| 190 |
+
<p align="center">🤗 <a href="https://huggingface.co/inclusionAI">Hugging Face</a> | 🤖 <a href="https://modelscope.cn/organization/inclusionAI">ModelScope </a> | 🐙 <a href="https://openrouter.ai/inclusionai/ling-3.0-flash:free">OpenRouter </a> </p>
|
| 191 |
+
|
| 192 |
+
## <font style="color:rgba(0, 0, 0, 0.88);">Introduction</font>
|
| 193 |
+
We're introducing Ling-3.0-flash, our next-generation native hybrid reasoning model. Operating with **124B** total and **5.1B** active parameters (~12.4% and ~8.1% of our previous 1T-class flagship Ring-2.6-1T), Ling-3.0-flash matches or outperforms its predecessor across key benchmarks.
|
| 194 |
+
|
| 195 |
+
<font style="color:rgb(16, 18, 20);">Key highlights of the model are summarized below:</font>
|
| 196 |
+
|
| 197 |
+
+ **Native Hybrid-Linear Architecture:** Ling-3.0 adopts a native hybrid linear attention architecture from the very start of pretraining (5:1 alternating stacking of Kimi Delta Attention (KDA) and MLA), upgraded with KDA fine-grained diagonal gating and 1/64 sparse MoE. With 124B total parameters and 5.1B activated parameters, it achieves a synergistic leap in long-context efficiency and computational cost.
|
| 198 |
+
+ **Remarkable Efficiency & Performance:** Engineered for speed, compute efficiency, and production deployment, Ling-3.0-flash delivers class-defying performance against both larger SOTA competitors and previous-generation flagships. Activating only 5.1B parameters per token, it provides impressive reasoning, instruction following, and long-context capabilities to empower complex agentic workflows in production environments.
|
| 199 |
+
+ **Comprehensive Agentic Evolution:** Tailored for real-world productivity workflows, the model incorporates 10,000+ interactive training environments to achieve end-to-end closed-loop execution across Coding, General, and Deep Research Agent tasks. It natively integrates the SGLang HiCache + Mooncake hierarchical caching architecture (featuring physical dual-pools and a cluster-shared L3 cache), eliminating redundant recomputation during long-horizon interactions and reducing Time to First Token (TTFT) by 60% to over 80% in long-input scenarios.s the SGLang HiCache + Mooncake hierarchical caching architecture (featuring physical dual-pools and a cluster-shared L3 cache), eliminating redundant recomputation during long-horizon interactions and reducing Time to First Token (TTFT) by 60% to over 80% in long-input scenarios.
|
| 200 |
+
|
| 201 |
+
<!-- 这是一张图片,ocr 内容为:SWE-BENCH MULTILINGUAL TERMINAL-BENCH 2.1 SWE-BENCHPRO TAU3-BANKING-AA LL088000LL 65 6 71.2 76.5 75.9 AP 28.0 60 0 72.4 73.3 56.6 56.2 56.3 71.0 53.9 70 22.9 55 57.0 50 47.9 48.3 60 56.7 14.6 45 11.3 71.3 39.3 39.0 70.1 50 8.9 40 42.7 40 34.1 35 30 30 WIDESEARCH MCP-ATLAS SKILLSBENCH BROWSECOMP 品质88品质品等学导新品 品民品品导品只只口 豆豆复品品导导导 品品&品品定品名品 6 4 79.5 米 0 75.2 73.6 74.4 70.2 69.0 82.0 66.7 6 65.5 62.2 53.5 75.8 61.2 73.2 71.7 74.0 55.2 53.6 52.6 49.4 G 20.3 19.5 71.9 31.3 MULTI-AGENT IFBENCH SYSBENCH MRCR-256K MULTI-IF 100 雪饼 110 110 87.7 89.3 79.2 06 82.9 84.6 86.2 84.6 84.8 75.7 82.3 93.6 91.4 93.9 90793.3949 72.6 84.3 90 品8888元 81.1 86.5 86.2 69.0 70 67.3 70 60 56.6 05 30 0 30 10 ULIO RING-2.6-1T(XHIGH) STEP-3.7-FLASH(HIGH) LING-3.0-FLASH MINIMAX-M2.7 WALBAN DEEPSEEK-V4-FLASH-PREVIEW(MAX) CLAUDE-SONNET-4.6(MAX) GPT-5.4-MINI(HIGH) NEMOTRON-3-SUPER-120B-A12B NOTE:THINKING MODE IS ENABLED BY DEFAULT. -->
|
| 202 |
+

|
| 203 |
+
|
| 204 |
+
## Model Overview
|
| 205 |
+
The model summary information and architecture diagram are as follows:
|
| 206 |
+
|
| 207 |
+
| Architecture | Hybrid-linear MoE |
|
| 208 |
+
| --- | --- |
|
| 209 |
+
| Parameter Scale | Totoal 124B, Activated 5.1B |
|
| 210 |
+
| Transformer Layers | 35 KDA + 7 Gated MLA (5:1) |
|
| 211 |
+
| Number of Dense Layers | 2 |
|
| 212 |
+
| Number of Routed Experts | 512 |
|
| 213 |
+
| Number of Shared Experts | 1 |
|
| 214 |
+
| Number of Activated Experts | 8 |
|
| 215 |
+
| Attention Heads | 32 |
|
| 216 |
+
| Hidden Size | 2560 |
|
| 217 |
+
| Expert Intermediate Size | 768 |
|
| 218 |
+
| Dense Intermediate Size | 6144 |
|
| 219 |
+
| Vocabulary Size | 157184 |
|
| 220 |
+
| Context Training Schedule | 8K -> 32K -> 256K |
|
| 221 |
+
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
|
| 225 |
+
<!-- 这是一张图片,ocr 内容为:LING-3.0-FLASH ARCHITECTURE TRAININGOBJECTIVE:NEXT-TOKENPRE TOKEN PREDICTION AND MULTI-TOKEN PREDICTION (MTP) VOCABULARY O:SIGMOID GATE OUTPUT LINEAR OUTPUT LAYER SIZE OF 157K PROJECTION FINAL RMSNORM MULTI-HEAD LATENT ATTENTION K E512A8+1SHARED MOE ROPE ROPE ERT,ALF-LB EXPERT RMSNORM LINEAR LINEAR RMSNORM RMSNORM SUPPORTED LINEAR LINEAR LINEAR GATED MLA ROPE CONTENTLENGTH-- OF 1M TOKENS RMSNORM O:SIGMOID GATE OUTPUT P:SOFTPLUS GATE PROJECTION 8:SWISH FUNC RMSNORM MOE KIMI DELTA ATTENTION RMSNORM K V L2 NORM LINEAR TIME 8 KDA COMPLEXITY RMSNORM CONV CONV MLP LINEAR TOKEN EMBEDDING LAYER 7 GROUPS LINEAR LINEAR FIRST 2 BLOCKS EMBEDDING TOKENIZED TEXT USE DENSE FFN DIMENSION OF 2,560 个 INSTEAD OF MOE SAMPLE INPUT TEXT -->
|
| 226 |
+

|
| 227 |
+
|
| 228 |
+
## Evaluation
|
| 229 |
+
We have conducted a comprehensive evaluation of Ling-3.0-flash across multiple authoritative benchmarks. **Ling-3.0-flash** performs strongly on representative code/agent benchmarks such as **SWE-Bench Pro, SWE-Bench Multilingual, Tau3-banking-AA**, **MCP-Atlas** and **SkillsBench, etc**. In practice, Ling-3.0-flash delivers a strong user experience across frameworks including **Claude Code**,**Kilo Code**,**Qwen Code**,**Hermes Agent**,and **OpenClaw**, etc. Beyond agentic tasks, Ling-3.0-flash also delivers strong performance across **general knowledge**,**mathematical reasoning**,**instruction following**,and **long-context understanding**.
|
| 230 |
+
|
| 231 |
+
<!-- 这是一张图片,ocr 内容为:DEEPSEEK CLAUDE- NEMOTRON- LING-3.0 GPT-5.4 STEP-3.7- V4-FLASH- RING-2.6-1T MINIMAX- 3-SUPER FLASH (HIGH) MINI (HIGH) FLASH (XHIGH) 120B-A12B (MAX) (MAX) 120B-A12B 124B-A5.1B 284B-A13B 198B-A11B 230B-A10B 1T-A63B SIZE CODING AGENT SWE-BENCH PRO 47.9 34.1 48.3 56.2 56.3 52.6 53.9 56.6 SWE-BENCH MULTILINGUAL 72.4 71.0 42.7 56.7 724 76.5 73.3 75.9 57.0 TERMINAL-BENCH 2.1 39.3 55.8 55.0 71.2 62.0 43.1 39.0 59.2 77.0 65.1 55.8 ARTIFACTSBENCH 66.8 64.0 51.6 68.7 25.3 19.2 MINIAPPENCH 28.0 14.8 46.3 20.7 58.8 5.8 52.2 ANTSWEBENCH 48.6 46.4 GENERAL AGENT 8.9 11.3 28.0 TAU3-BANKING-AA 11.3 10.1 22.9 14.6 30.5 55.2 53.6 69.0 65.5 MCP-ATLAS 52.6 61.2 49.4 66.7 53.5 24.9 20.3 44.8 54.4 28.4 44.8 11.9 SKILLSBENCH BFCL-V4 59.5 73.0 68.3 73.1 65.4 63.6 60.6 64.8 GDPVAL V2-AA 920 1377 1189 1017 1107 699 1159 SEARCH AGENT WIDESEARCH 75.2 70.2 62.2 73.6 19.5 74.4 56.8 79.5 72.2(W/ CTX) 74.0(W/CTX) BROWSECOMP 73.2 71.7 31.3 75.8 76.3 82.0(MA) 82.1(MA) DRACO 71.3 75.8 61.3 66.8 70.4 INSTRUCTION FOLLOWING 75.7 74.5 IFBENCH 72.6 67.3 79.2 69.0 44.6 56.6 91.4 93.6 93.3 SYSBENCH 86.5 93.9 90.7 86.2 94.9 77.3 71.3 LIFEBENCH 69.2 72.5 71.8 74.1 66.9 60.2 REASONING 91.7 94.2 AIME26 93.2 95.0 95.8 92.9 96.5 94.4 HMMT-FEB26 87.0 71.9 93.5 85.6 94.8 87.9 84.9 83.9 83.7 74.5 87.0 IMO-ANSWERBENCH 77.0 82.1 86.1 66.9 22.7 HLE 19.9 20.6 18.3 18.3 34.8 28.1 30.0 LIVECODEBENCH 82.8 78.1 80.8 87.0 75.6 83.7 78.7 91.6 (2408-2505) LONG CONTEXT & MULTI-TURN DIALOGUE 39.2 MRCR 128K 27.7 90.1 56.1 40.8 90.8 92.5 88.5 92.7 81.1 MRCR 256K 25.7 76.5 50.5 35.8 84.3 70.7 AA-LCR 65.1 64.3 68.7 63.7 63.0 58.3 63.4 89.3 MULTI-IF 86.2 87.7 82.9 84.6 84.8 82.3 84.6 -->
|
| 232 |
+

|
| 233 |
+
|
| 234 |
+
> + Thinking mode is enabled by default. Unless otherwise specified, the default parameters for Ling-3.0-flash are as follows: `temperature=0.6, top_p=0.95, top_k=20`.
|
| 235 |
+
> + <font style="color:rgb(16, 18, 20);">SWE-Bench Series:Evaluated using OpenHands as the agent harness with tailored prompts. Decoding uses </font>`temperature=0.6, top_p=0.95, max_new_tokens=32K`<font style="color:rgb(16, 18, 20);">, with a 256K context window.</font>
|
| 236 |
+
> + <font style="color:rgb(16, 18, 20);">Terminal-Bench 2.1: Evaluated under the Artificial Analysis (AA) protocol using the default Terminus 2 harness, a unified 2-hour timeout, the provided JSON parser in preserve-thinking mode, and 3 runs per task (mean). Decoding uses </font>`temperature=0.6, top_p=1.0, max_new_tokens=32K`<font style="color:rgb(16, 18, 20);">, with a 256K context window.</font>
|
| 237 |
+
> + <font style="color:rgb(16, 18, 20);">MiniAppBench: A 500-task coding benchmark evaluating whether models can turn a single user request into complete, usable interactive HTML apps in real-world application-generation scenarios. Evaluated with `temperature=1.0, top_p=1.0, max_tokens=128K`.
|
| 238 |
+
> + <font style="color:rgb(16, 18, 20);">AntSWEBench: </font><font style="color:rgb(0, 0, 0);">AntSWEBench is an internally used software engineering benchmark that covers mainstream programming languages such as Java, JavaScript, and Python, including various development scenarios like new feature, bug fix, and code refactoring.</font>
|
| 239 |
+
> + <font style="color:rgb(16, 18, 20);">Tau3-banking-AA: Aligned with the AA leaderboard, utilizing GPT-5.4-mini (medium reasoning) for both the user simulator and the natural-language assertion judge.</font>
|
| 240 |
+
> + MCP-Atlas: Evaluated on the 500-task public set using the official v1 harness with a 20-turn limit and Gemini-2.5-Pro as the claim-coverage judger.
|
| 241 |
+
> + SkillsBench: Evaluated via kilo-code on 87 tasks (excluding external API-dependent tasks), averaged over 3 runs.
|
| 242 |
+
> + <font style="color:rgb(16, 18, 20);">GDPval v2-AA : Evaluated on the public 220-task benchmark using the official Stirrup harness, with a 250-turn limit and a 5-hour timeout.</font>
|
| 243 |
+
> + <font style="color:rgb(16, 18, 20);">Search‑agent:For all search‑agent tasks, evaluations are performed using an internal harness. The basic ReAct paradigm is adopted for single-agent evaluation, while a multi-agent setup is employed for BrowseComp. The reported metric is the average pass@1.</font>
|
| 244 |
+
> - <font style="color:rgb(16, 18, 20);">WideSearch: Evaluated using the official prompt and the official judge model GPT-4.1 on the corrected version of the dataset.</font>
|
| 245 |
+
> - <font style="color:rgb(16, 18, 20);">Draco: Scored based on official rubrics per question, with the final score calculated as the average across all questions using </font>Claude Opus 4.6<font style="color:rgb(16, 18, 20);"> as the scoring model.</font>
|
| 246 |
+
> - BrowseComp (Single-Agent): Evaluated using a resume strategy for context management: once the context reaches a 64K-token threshold, the trajectory is summarized, the original history is discarded, and execution is resumed from the summary.
|
| 247 |
+
> - BrowseComp (Multi-Agent):<font style="color:rgb(16, 18, 20);"> Evaluated on English and ZH Revised datasets using an internal multi-agent search harness based on SearchSwarm/Tongyi DeepResearch, configured with </font>`temperature=0.85, top_p=0.95, max_tokens=8K`<font style="color:rgb(16, 18, 20);">, and main/sub-agent context windows of 128K and 64K, respectively.</font>
|
| 248 |
+
>
|
| 249 |
+
|
| 250 |
+
## Quickstart
|
| 251 |
+
### SGlang
|
| 252 |
+
#### Install our SGLang
|
| 253 |
+
```bash
|
| 254 |
+
pip install uv
|
| 255 |
+
|
| 256 |
+
uv venv ~/my_ling_env
|
| 257 |
+
|
| 258 |
+
source ~/my_ling_env/bin/activate
|
| 259 |
+
|
| 260 |
+
git clone -b ling_v3_support https://github.com/inclusionAI/sglang_ling_v3.git
|
| 261 |
+
|
| 262 |
+
cd sglang_ling_v3
|
| 263 |
+
|
| 264 |
+
pip install --upgrade pip
|
| 265 |
+
|
| 266 |
+
pip install -e "python"
|
| 267 |
+
```
|
| 268 |
+
|
| 269 |
+
#### Run Inference
|
| 270 |
+
Here is an example to run Ling-3.0-flash with 4 GPUs, where the master node IP is `${MASTER_IP}` and server port is `${PORT}`:
|
| 271 |
+
|
| 272 |
+
**Server**
|
| 273 |
+
|
| 274 |
+
Since the model is trained with MTP, we recommend enabling MTP during inference (i.e., --speculative-algorithm NEXTN) for lower latency.
|
| 275 |
+
|
| 276 |
+
```bash
|
| 277 |
+
export SGLANG_ALLOW_OVERWRITE_LONGER_CONTEXT_LEN=1
|
| 278 |
+
export SGLANG_JIT_DEEPGEMM_PRECOMPILE=1
|
| 279 |
+
export SGLANG_ENABLE_SPEC_V2=1
|
| 280 |
+
python -m sglang.launch_server \
|
| 281 |
+
--model-path $MODEL_PATH \
|
| 282 |
+
--dist-init-addr $MASTER_IP:2345 \
|
| 283 |
+
--port $PORT \
|
| 284 |
+
--nnodes 1 \
|
| 285 |
+
--mem-fraction-static 0.8 \
|
| 286 |
+
--max-running-requests 64 \
|
| 287 |
+
--tp-size 4 \
|
| 288 |
+
--chunked-prefill-size 8192 \
|
| 289 |
+
--tool-call-parser ling3 \
|
| 290 |
+
--reasoning-parser ling3 \
|
| 291 |
+
--context-length 262144 \
|
| 292 |
+
--speculative-algorithm NEXTN \
|
| 293 |
+
--max-mamba-cache-size 320 \
|
| 294 |
+
--enable-fp32-lm-head \
|
| 295 |
+
--disable-shared-experts-fusion
|
| 296 |
+
```
|
| 297 |
+
|
| 298 |
+
**Client**
|
| 299 |
+
|
| 300 |
+
We recommend using the sampling parameters `temperature=0.6`, `top_p=0.95`, and `top_k=20`, and enabling `enable_thinking` for better performance.
|
| 301 |
+
|
| 302 |
+
```bash
|
| 303 |
+
curl -s http://${MASTER_IP}:${PORT}/v1/chat/completions \
|
| 304 |
+
-H "Content-Type: application/json" \
|
| 305 |
+
-d '{"model": "auto",
|
| 306 |
+
"messages": [{"role": "user", "content": "hello!"}],
|
| 307 |
+
"chat_template_kwargs": {"enable_thinking": true},
|
| 308 |
+
"stream": true,
|
| 309 |
+
"temperature": 0.6,
|
| 310 |
+
"top_k": 20,
|
| 311 |
+
"top_p": 0.95
|
| 312 |
+
}'
|
| 313 |
+
```
|
| 314 |
+
|
| 315 |
+
### vLLM
|
| 316 |
+
#### Install our vLLM
|
| 317 |
+
```bash
|
| 318 |
+
pip install uv
|
| 319 |
+
|
| 320 |
+
uv venv ~/my_ling_env
|
| 321 |
+
|
| 322 |
+
source ~/my_ling_env/bin/activate
|
| 323 |
+
|
| 324 |
+
git clone -b ling_3_0 https://github.com/inclusionAI/vllm-ling-v3.git
|
| 325 |
+
|
| 326 |
+
cd vllm-ling-v3
|
| 327 |
+
|
| 328 |
+
VLLM_USE_PRECOMPILED=1 uv pip install --editable . --torch-backend=auto
|
| 329 |
+
```
|
| 330 |
+
|
| 331 |
+
#### Run Inference
|
| 332 |
+
Here is the example to run Ling-3.0-flash with 4 GPUs, where the server port is `${PORT}`:
|
| 333 |
+
|
| 334 |
+
**Server**
|
| 335 |
+
|
| 336 |
+
Since the model is trained with MTP, we recommend enabling MTP during inference (i.e., --speculative-config) for lower latency.
|
| 337 |
+
|
| 338 |
+
```bash
|
| 339 |
+
vllm serve "$MODEL_PATH" \
|
| 340 |
+
--port "$PORT" \
|
| 341 |
+
--trust-remote-code \
|
| 342 |
+
--served-model-name auto \
|
| 343 |
+
--tensor-parallel-size 4 \
|
| 344 |
+
--gpu-memory-utilization 0.85 \
|
| 345 |
+
--enable-prefix-caching \
|
| 346 |
+
--mamba-cache-mode align \
|
| 347 |
+
--enable-auto-tool-choice \
|
| 348 |
+
--tool-call-parser ling3 \
|
| 349 |
+
--reasoning-parser ling3 \
|
| 350 |
+
--speculative-config '{"method":"mtp","num_speculative_tokens":3}'
|
| 351 |
+
```
|
| 352 |
+
|
| 353 |
+
**Client**
|
| 354 |
+
|
| 355 |
+
We recommend using the sampling parameters `temperature=0.6`, `top_p=0.95`, and `top_k=20`, and enabling `enable_thinking` for better performance.
|
| 356 |
+
|
| 357 |
+
```bash
|
| 358 |
+
curl -s http://${MASTER_IP}:${PORT}/v1/chat/completions \
|
| 359 |
+
-H "Content-Type: application/json" \
|
| 360 |
+
-d '{"model": "auto",
|
| 361 |
+
"messages": [{"role": "user", "content": "hello!"}],
|
| 362 |
+
"chat_template_kwargs": {"enable_thinking": true},
|
| 363 |
+
"stream": true,
|
| 364 |
+
"temperature": 0.6,
|
| 365 |
+
"top_k": 20,
|
| 366 |
+
"top_p": 0.95
|
| 367 |
+
}'
|
| 368 |
+
```
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{#- Bailing V3 chat template -#}
|
| 2 |
+
{#- Supports: thinking option, tool calling -#}
|
| 3 |
+
|
| 4 |
+
{#- ==================== thinking option normalization ==================== -#}
|
| 5 |
+
{%- if enable_thinking is defined %}
|
| 6 |
+
{%- if enable_thinking %}
|
| 7 |
+
{%- set thinking_option = 'on' %}
|
| 8 |
+
{%- else %}
|
| 9 |
+
{%- set thinking_option = 'off' %}
|
| 10 |
+
{%- endif %}
|
| 11 |
+
{%- elif thinking_option is not defined %}
|
| 12 |
+
{%- set thinking_option = 'on' %}
|
| 13 |
+
{%- endif %}
|
| 14 |
+
|
| 15 |
+
{#- ==================== preserved thinking ==================== -#}
|
| 16 |
+
{% set preserved_thinking = true %}
|
| 17 |
+
|
| 18 |
+
{#- ==================== system message ==================== -#}
|
| 19 |
+
{{- '<role>SYSTEM</role>' }}
|
| 20 |
+
{%- if tools %}
|
| 21 |
+
{%- if messages[0].role == 'system' %}
|
| 22 |
+
{{- messages[0].content + '\n' }}
|
| 23 |
+
{%- endif %}
|
| 24 |
+
{{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
|
| 25 |
+
{%- for tool in tools %}
|
| 26 |
+
{{- "\n" }}
|
| 27 |
+
{{- tool | tojson }}
|
| 28 |
+
{%- endfor %}
|
| 29 |
+
{{- "\n</tools>\n\nIf none of the functions can be used, point it out. If the given question lacks the parameters required by the function, also point it out.\nIf you need to use a function, for each function call, output the function name and arguments within the following XML format:\n<tool_call>{function-name}\n<arg_key>{arg-key-1}</arg_key>\n<arg_value>{arg-value-1}</arg_value>\n<arg_key>{arg-key-2}</arg_key>\n<arg_value>{arg-value-2}</arg_value>\n...\n</tool_call>\n" }}
|
| 30 |
+
{%- if messages[0].role == 'system' and messages[0].content is string and ('detailed thinking on' in messages[0].content or 'detailed thinking off' in messages[0].content) %}
|
| 31 |
+
{{- '<|role_end|>' }}
|
| 32 |
+
{%- else %}
|
| 33 |
+
{{- 'detailed thinking ' + thinking_option + '<|role_end|>' }}
|
| 34 |
+
{%- endif %}
|
| 35 |
+
{%- else %}
|
| 36 |
+
{%- if messages[0].role == 'system' %}
|
| 37 |
+
{%- if 'detailed thinking on' in messages[0].content or 'detailed thinking off' in messages[0].content %}
|
| 38 |
+
{{- messages[0].content + '<|role_end|>' }}
|
| 39 |
+
{%- else %}
|
| 40 |
+
{{- messages[0].content + '\n' }}
|
| 41 |
+
{{- 'detailed thinking ' + thinking_option + '<|role_end|>' }}
|
| 42 |
+
{%- endif %}
|
| 43 |
+
{% else %}
|
| 44 |
+
{{- 'detailed thinking ' + thinking_option + '<|role_end|>' }}
|
| 45 |
+
{%- endif %}
|
| 46 |
+
{%- endif %}
|
| 47 |
+
{%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
|
| 48 |
+
{%- for message in messages[::-1] %}
|
| 49 |
+
{%- set index = (messages|length - 1) - loop.index0 %}
|
| 50 |
+
{%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}
|
| 51 |
+
{%- set ns.multi_step_tool = false %}
|
| 52 |
+
{%- set ns.last_query_index = index %}
|
| 53 |
+
{%- endif %}
|
| 54 |
+
{%- endfor %}
|
| 55 |
+
{%- for message in messages %}
|
| 56 |
+
{%- if message.content is string %}
|
| 57 |
+
{%- set content = message.content %}
|
| 58 |
+
{%- else %}
|
| 59 |
+
{%- set content = '' %}
|
| 60 |
+
{%- endif %}
|
| 61 |
+
{%- if message.role == "user" %}
|
| 62 |
+
{{- '<role>HUMAN</role>' + message.content + '<|role_end|>' }}
|
| 63 |
+
{%- elif message.role == "system" and not loop.first %}
|
| 64 |
+
{{- '<role>SYSTEM</role>' + message.content + '<|role_end|>' }}
|
| 65 |
+
{%- elif message.role == "assistant" %}
|
| 66 |
+
{%- set reasoning_content = '' %}
|
| 67 |
+
{%- if message.reasoning_content is string and message.reasoning_content != '' %}
|
| 68 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 69 |
+
{%- else %}
|
| 70 |
+
{%- if '</think>' in content %}
|
| 71 |
+
{%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
|
| 72 |
+
{%- set content = content.split('</think>')[-1].lstrip('\n') %}
|
| 73 |
+
{%- endif %}
|
| 74 |
+
{%- endif %}
|
| 75 |
+
{%- if preserved_thinking or loop.index0 > ns.last_query_index %}
|
| 76 |
+
{%- if reasoning_content != '' %}
|
| 77 |
+
{{- '<role>ASSISTANT</role>' + '\n<think>' + reasoning_content.strip('\n') + '</think>' + content.lstrip('\n') }}
|
| 78 |
+
{%- else %}
|
| 79 |
+
{{- '<role>ASSISTANT</role>\n<think></think>' + content }}
|
| 80 |
+
{%- endif %}
|
| 81 |
+
{%- else %}
|
| 82 |
+
{{- '<role>ASSISTANT</role>\n<think></think>' + content }}
|
| 83 |
+
{%- endif %}
|
| 84 |
+
{%- if message.tool_calls %}
|
| 85 |
+
{%- for tool_call in message.tool_calls %}
|
| 86 |
+
{%- if (loop.first and content) or (not loop.first) %}
|
| 87 |
+
{{- '\n' }}
|
| 88 |
+
{%- endif %}
|
| 89 |
+
{%- set tc = tool_call %}
|
| 90 |
+
{%- if tool_call.function %}
|
| 91 |
+
{%- set tc = tool_call.function %}
|
| 92 |
+
{%- endif %}
|
| 93 |
+
{{- '<tool_call>' + tc.name }}
|
| 94 |
+
{% set _args = tc.arguments %}
|
| 95 |
+
{%- for k, v in _args.items() %}
|
| 96 |
+
{{- '<arg_key>' + k + '</arg_key>' }}
|
| 97 |
+
{{- '\n<arg_value>' }}
|
| 98 |
+
{%- if v is string %}
|
| 99 |
+
{{- v }}
|
| 100 |
+
{%- else %}
|
| 101 |
+
{{- v | tojson(ensure_ascii=False) }}
|
| 102 |
+
{%- endif %}
|
| 103 |
+
{{- '</arg_value>' }}
|
| 104 |
+
{%- endfor %}
|
| 105 |
+
{{- '\n</tool_call>' }}
|
| 106 |
+
{%- endfor %}
|
| 107 |
+
{%- endif %}
|
| 108 |
+
{{- '<|role_end|>' }}
|
| 109 |
+
{%- elif message.role == "tool" %}
|
| 110 |
+
{%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
|
| 111 |
+
{{- '<role>OBSERVATION</role>' }}
|
| 112 |
+
{%- endif %}
|
| 113 |
+
{{- '\n<tool_response>\n' }}
|
| 114 |
+
{{- content }}
|
| 115 |
+
{{- '\n</tool_response>' }}
|
| 116 |
+
{%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
|
| 117 |
+
{{- '<|role_end|>' }}
|
| 118 |
+
{%- endif %}
|
| 119 |
+
{%- endif %}
|
| 120 |
+
{%- endfor %}
|
| 121 |
+
|
| 122 |
+
{#- ==================== generation prompt ==================== -#}
|
| 123 |
+
{%- if add_generation_prompt %}
|
| 124 |
+
{{- '<role>ASSISTANT</role>' }}
|
| 125 |
+
{%- if thinking_option == 'on' %}
|
| 126 |
+
{{- '\n<think>' }}
|
| 127 |
+
{%- elif thinking_option == 'off' %}
|
| 128 |
+
{{- '\n<think></think>' }}
|
| 129 |
+
{%- endif %}
|
| 130 |
+
{%- endif %}
|
config.json
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"architectures": [
|
| 3 |
+
"BailingMoeV3ForCausalLM"
|
| 4 |
+
],
|
| 5 |
+
"attention_dropout": 0.0,
|
| 6 |
+
"auto_map": {
|
| 7 |
+
"AutoConfig": "configuration_bailing_moe_v3.BailingMoeV3Config",
|
| 8 |
+
"AutoModel": "modeling_bailing_moe_v3.BailingMoeV3Model",
|
| 9 |
+
"AutoModelForCausalLM": "modeling_bailing_moe_v3.BailingMoeV3ForCausalLM"
|
| 10 |
+
},
|
| 11 |
+
"embedding_dropout": 0.0,
|
| 12 |
+
"eos_token_id": 156895,
|
| 13 |
+
"expert_swiglu_limit_list": [
|
| 14 |
+
0,
|
| 15 |
+
0,
|
| 16 |
+
0,
|
| 17 |
+
0,
|
| 18 |
+
0,
|
| 19 |
+
0,
|
| 20 |
+
0,
|
| 21 |
+
0,
|
| 22 |
+
0,
|
| 23 |
+
0,
|
| 24 |
+
0,
|
| 25 |
+
0,
|
| 26 |
+
0,
|
| 27 |
+
0,
|
| 28 |
+
0,
|
| 29 |
+
0,
|
| 30 |
+
0,
|
| 31 |
+
0,
|
| 32 |
+
0,
|
| 33 |
+
0,
|
| 34 |
+
0,
|
| 35 |
+
0,
|
| 36 |
+
0,
|
| 37 |
+
0,
|
| 38 |
+
0,
|
| 39 |
+
0,
|
| 40 |
+
0,
|
| 41 |
+
0,
|
| 42 |
+
0,
|
| 43 |
+
0,
|
| 44 |
+
0,
|
| 45 |
+
0,
|
| 46 |
+
0,
|
| 47 |
+
0,
|
| 48 |
+
0,
|
| 49 |
+
4,
|
| 50 |
+
4,
|
| 51 |
+
4,
|
| 52 |
+
4,
|
| 53 |
+
4,
|
| 54 |
+
4,
|
| 55 |
+
4
|
| 56 |
+
],
|
| 57 |
+
"first_k_dense_replace": 2,
|
| 58 |
+
"gated_attention_proj_granularity_type": "head_wise",
|
| 59 |
+
"group_norm_size": 1,
|
| 60 |
+
"head_dim": 128,
|
| 61 |
+
"hidden_act": "silu",
|
| 62 |
+
"hidden_size": 2560,
|
| 63 |
+
"initializer_range": 0.02,
|
| 64 |
+
"intermediate_size": 6144,
|
| 65 |
+
"kda_lower_bound": -5.0,
|
| 66 |
+
"kda_safe_gate": true,
|
| 67 |
+
"kv_lora_rank": 512,
|
| 68 |
+
"layer_group_size": 6,
|
| 69 |
+
"linear_silu": true,
|
| 70 |
+
"max_position_embeddings": 131072,
|
| 71 |
+
"max_window_layers": 20,
|
| 72 |
+
"moe_intermediate_size": 768,
|
| 73 |
+
"moe_router_enable_expert_bias": true,
|
| 74 |
+
"moe_shared_expert_intermediate_size": 768,
|
| 75 |
+
"mtp_loss_scaling_factor": 0,
|
| 76 |
+
"mtp_use_kda": false,
|
| 77 |
+
"n_group": 8,
|
| 78 |
+
"no_kda_lora": true,
|
| 79 |
+
"norm_topk_prob": true,
|
| 80 |
+
"num_attention_heads": 32,
|
| 81 |
+
"num_experts": 512,
|
| 82 |
+
"num_experts_per_tok": 8,
|
| 83 |
+
"num_hidden_layers": 42,
|
| 84 |
+
"num_key_value_heads": 32,
|
| 85 |
+
"num_kv_heads_for_linear_attn": 0,
|
| 86 |
+
"num_nextn_predict_layers": 1,
|
| 87 |
+
"num_shared_experts": 1,
|
| 88 |
+
"output_dropout": 0.0,
|
| 89 |
+
"output_router_logits": false,
|
| 90 |
+
"pad_token_id": 156892,
|
| 91 |
+
"partial_rotary_factor": 0.5,
|
| 92 |
+
"q_lora_rank": null,
|
| 93 |
+
"qk_head_dim": 192,
|
| 94 |
+
"qk_nope_head_dim": 128,
|
| 95 |
+
"qk_rope_head_dim": 64,
|
| 96 |
+
"rms_norm_eps": 1e-06,
|
| 97 |
+
"rope_interleave": true,
|
| 98 |
+
"rope_scaling": null,
|
| 99 |
+
"rope_theta": 6000000,
|
| 100 |
+
"rotary_dim": 64,
|
| 101 |
+
"routed_scaling_factor": 2.5,
|
| 102 |
+
"router_dtype": "fp32",
|
| 103 |
+
"scale_router_input": false,
|
| 104 |
+
"score_function": "sigmoid",
|
| 105 |
+
"scoring_func": "sigmoid",
|
| 106 |
+
"seq_aux": true,
|
| 107 |
+
"share_expert_swiglu_limit_list": [
|
| 108 |
+
0,
|
| 109 |
+
0,
|
| 110 |
+
0,
|
| 111 |
+
0,
|
| 112 |
+
0,
|
| 113 |
+
0,
|
| 114 |
+
0,
|
| 115 |
+
0,
|
| 116 |
+
0,
|
| 117 |
+
0,
|
| 118 |
+
0,
|
| 119 |
+
0,
|
| 120 |
+
0,
|
| 121 |
+
0,
|
| 122 |
+
0,
|
| 123 |
+
0,
|
| 124 |
+
0,
|
| 125 |
+
0,
|
| 126 |
+
0,
|
| 127 |
+
0,
|
| 128 |
+
0,
|
| 129 |
+
0,
|
| 130 |
+
0,
|
| 131 |
+
0,
|
| 132 |
+
0,
|
| 133 |
+
0,
|
| 134 |
+
0,
|
| 135 |
+
0,
|
| 136 |
+
0,
|
| 137 |
+
0,
|
| 138 |
+
0,
|
| 139 |
+
0,
|
| 140 |
+
0,
|
| 141 |
+
0,
|
| 142 |
+
5,
|
| 143 |
+
5,
|
| 144 |
+
5,
|
| 145 |
+
5,
|
| 146 |
+
5,
|
| 147 |
+
5,
|
| 148 |
+
7,
|
| 149 |
+
7
|
| 150 |
+
],
|
| 151 |
+
"short_conv_kernel_size": 4,
|
| 152 |
+
"tie_word_embeddings": false,
|
| 153 |
+
"topk_group": 4,
|
| 154 |
+
"topk_method": "noaux_tc",
|
| 155 |
+
"transformers_version": "4.45.0",
|
| 156 |
+
"up_proj_norm": false,
|
| 157 |
+
"use_bias": false,
|
| 158 |
+
"use_cache": true,
|
| 159 |
+
"use_kda_lora": false,
|
| 160 |
+
"use_mla_nope": false,
|
| 161 |
+
"use_nGPT": false,
|
| 162 |
+
"use_qk_norm": true,
|
| 163 |
+
"use_qkv_bias": false,
|
| 164 |
+
"v_head_dim": 128,
|
| 165 |
+
"value_norm": false,
|
| 166 |
+
"vocab_size": 157184,
|
| 167 |
+
"model_type": "bailing_hybrid",
|
| 168 |
+
"torch_dtype": "bfloat16",
|
| 169 |
+
"quantization_config": {
|
| 170 |
+
"quant_method": "compressed-tensors",
|
| 171 |
+
"format": "nvfp4-pack-quantized",
|
| 172 |
+
"config_groups": {
|
| 173 |
+
"group_0": {
|
| 174 |
+
"targets": [
|
| 175 |
+
"re:.*\\.experts\\.\\d+\\..*",
|
| 176 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.experts\\.\\d+\\.gate_up_proj$"
|
| 177 |
+
],
|
| 178 |
+
"weights": {
|
| 179 |
+
"num_bits": 4,
|
| 180 |
+
"type": "float",
|
| 181 |
+
"strategy": "tensor_group",
|
| 182 |
+
"group_size": 16,
|
| 183 |
+
"symmetric": true
|
| 184 |
+
}
|
| 185 |
+
}
|
| 186 |
+
},
|
| 187 |
+
"ignore": [
|
| 188 |
+
"re:.*lm_head$",
|
| 189 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.b_proj$",
|
| 190 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.f_proj$",
|
| 191 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.g_proj$",
|
| 192 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.k_conv1d$",
|
| 193 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.k_proj$",
|
| 194 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.o_proj$",
|
| 195 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.q_conv1d$",
|
| 196 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.q_proj$",
|
| 197 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.v_conv1d$",
|
| 198 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.v_proj$",
|
| 199 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.down_proj$",
|
| 200 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.gate_proj$",
|
| 201 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.up_proj$",
|
| 202 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.gate$",
|
| 203 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.shared_experts\\.down_proj$",
|
| 204 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.shared_experts\\.gate_proj$",
|
| 205 |
+
"re:.*model\\.layers\\.\\d+\\.mlp\\.shared_experts\\.up_proj$",
|
| 206 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.dense$",
|
| 207 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.kv_a_proj_with_mqa$",
|
| 208 |
+
"re:.*model\\.layers\\.\\d+\\.attention\\.kv_b_proj$",
|
| 209 |
+
"re:.*model\\.layers\\.\\d+\\.eh_proj$",
|
| 210 |
+
"re:.*model\\.word_embeddings$"
|
| 211 |
+
]
|
| 212 |
+
}
|
| 213 |
+
}
|
configuration_bailing_moe_v3.py
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Bailing MoE V2 model configuration"""
|
| 2 |
+
|
| 3 |
+
from transformers.configuration_utils import PretrainedConfig
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class BailingMoeV3Config(PretrainedConfig):
|
| 7 |
+
|
| 8 |
+
def __init__(
|
| 9 |
+
self,
|
| 10 |
+
vocab_size=157184,
|
| 11 |
+
hidden_size=2048,
|
| 12 |
+
intermediate_size=5120,
|
| 13 |
+
num_hidden_layers=20,
|
| 14 |
+
num_attention_heads=16,
|
| 15 |
+
num_key_value_heads=4,
|
| 16 |
+
hidden_act="silu",
|
| 17 |
+
use_qkv_bias=False, # bailing only
|
| 18 |
+
use_bias=False, # bailing only
|
| 19 |
+
rms_norm_eps=1e-06,
|
| 20 |
+
tie_word_embeddings=False, # PretrainedConfig key, here change default value.
|
| 21 |
+
embedding_dropout=0.0,
|
| 22 |
+
attention_dropout=0.0,
|
| 23 |
+
output_dropout=0.0,
|
| 24 |
+
initializer_range=0.02,
|
| 25 |
+
max_position_embeddings=32768,
|
| 26 |
+
rope_theta=600000.0,
|
| 27 |
+
use_cache=True,
|
| 28 |
+
max_window_layers=20,
|
| 29 |
+
rope_scaling=None,
|
| 30 |
+
pad_token_id=156892,
|
| 31 |
+
eos_token_id=156892,
|
| 32 |
+
num_experts=256,
|
| 33 |
+
num_shared_experts=1,
|
| 34 |
+
num_experts_per_tok=8,
|
| 35 |
+
n_group=8,
|
| 36 |
+
topk_group=4,
|
| 37 |
+
moe_intermediate_size=512,
|
| 38 |
+
moe_shared_expert_intermediate_size=512,
|
| 39 |
+
first_k_dense_replace=1,
|
| 40 |
+
head_dim=128,
|
| 41 |
+
output_router_logits=False,
|
| 42 |
+
use_qk_norm=True,
|
| 43 |
+
num_nextn_predict_layers=0,
|
| 44 |
+
mtp_loss_scaling_factor=0,
|
| 45 |
+
moe_router_enable_expert_bias=True,
|
| 46 |
+
routed_scaling_factor=1.0,
|
| 47 |
+
layer_group_size=5,
|
| 48 |
+
kv_lora_rank=512,
|
| 49 |
+
q_lora_rank=None,
|
| 50 |
+
qk_rope_head_dim=64,
|
| 51 |
+
v_head_dim=128,
|
| 52 |
+
qk_nope_head_dim=128,
|
| 53 |
+
rope_interleave=True,
|
| 54 |
+
score_function="sigmoid",
|
| 55 |
+
scoring_func="sigmoid",
|
| 56 |
+
seq_aux=True,
|
| 57 |
+
topk_method="noaux_tc",
|
| 58 |
+
router_dtype="fp32",
|
| 59 |
+
gated_attention_proj_granularity_type=None,
|
| 60 |
+
no_kda_lora=False,
|
| 61 |
+
kda_safe_gate=False,
|
| 62 |
+
kda_lower_bound=None,
|
| 63 |
+
short_conv_kernel_size=4,
|
| 64 |
+
**kwargs,
|
| 65 |
+
):
|
| 66 |
+
self.num_hidden_layers = num_hidden_layers
|
| 67 |
+
self.vocab_size = vocab_size
|
| 68 |
+
self.hidden_size = hidden_size
|
| 69 |
+
self.intermediate_size = intermediate_size
|
| 70 |
+
self.num_attention_heads = num_attention_heads
|
| 71 |
+
self.num_key_value_heads = num_key_value_heads
|
| 72 |
+
self.hidden_act = hidden_act
|
| 73 |
+
self.use_qkv_bias = use_qkv_bias
|
| 74 |
+
self.use_bias = use_bias
|
| 75 |
+
self.rms_norm_eps = rms_norm_eps
|
| 76 |
+
self.embedding_dropout = embedding_dropout
|
| 77 |
+
self.attention_dropout = attention_dropout
|
| 78 |
+
self.output_dropout = output_dropout
|
| 79 |
+
self.num_nextn_predict_layers = num_nextn_predict_layers
|
| 80 |
+
self.mtp_loss_scaling_factor = mtp_loss_scaling_factor
|
| 81 |
+
self.initializer_range = initializer_range
|
| 82 |
+
self.max_position_embeddings = max_position_embeddings
|
| 83 |
+
self.rope_theta = rope_theta
|
| 84 |
+
self.use_cache = use_cache
|
| 85 |
+
self.max_window_layers = max_window_layers
|
| 86 |
+
self.head_dim = head_dim or self.hidden_size // self.num_attention_heads
|
| 87 |
+
self.rope_scaling = rope_scaling
|
| 88 |
+
self.use_qk_norm = use_qk_norm
|
| 89 |
+
self.moe_router_enable_expert_bias = moe_router_enable_expert_bias
|
| 90 |
+
self.routed_scaling_factor = routed_scaling_factor
|
| 91 |
+
|
| 92 |
+
# MoE configs
|
| 93 |
+
self.num_experts = num_experts
|
| 94 |
+
self.num_shared_experts = num_shared_experts
|
| 95 |
+
self.num_experts_per_tok = num_experts_per_tok
|
| 96 |
+
self.n_group = n_group
|
| 97 |
+
self.topk_group = topk_group
|
| 98 |
+
self.moe_intermediate_size = moe_intermediate_size
|
| 99 |
+
self.moe_shared_expert_intermediate_size = moe_shared_expert_intermediate_size
|
| 100 |
+
self.first_k_dense_replace = first_k_dense_replace
|
| 101 |
+
self.output_router_logits = output_router_logits
|
| 102 |
+
|
| 103 |
+
# Linear configs
|
| 104 |
+
self.layer_group_size = layer_group_size
|
| 105 |
+
# mla
|
| 106 |
+
self.kv_lora_rank = kv_lora_rank
|
| 107 |
+
self.q_lora_rank = q_lora_rank
|
| 108 |
+
self.qk_rope_head_dim = qk_rope_head_dim
|
| 109 |
+
|
| 110 |
+
self.score_function = score_function
|
| 111 |
+
self.scoring_func = scoring_func
|
| 112 |
+
self.seq_aux = seq_aux
|
| 113 |
+
self.topk_method = topk_method
|
| 114 |
+
self.v_head_dim = v_head_dim
|
| 115 |
+
self.qk_nope_head_dim = qk_nope_head_dim
|
| 116 |
+
self.qk_head_dim = qk_nope_head_dim + qk_rope_head_dim
|
| 117 |
+
self.rope_interleave = rope_interleave
|
| 118 |
+
self.router_dtype = router_dtype
|
| 119 |
+
self.gated_attention_proj_granularity_type = gated_attention_proj_granularity_type
|
| 120 |
+
self.no_kda_lora = no_kda_lora
|
| 121 |
+
self.kda_safe_gate = kda_safe_gate
|
| 122 |
+
self.kda_lower_bound = kda_lower_bound
|
| 123 |
+
self.short_conv_kernel_size = short_conv_kernel_size
|
| 124 |
+
super().__init__(
|
| 125 |
+
pad_token_id=pad_token_id, eos_token_id=eos_token_id, tie_word_embeddings=tie_word_embeddings, **kwargs
|
| 126 |
+
)
|
model-00001-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5cd9b840d449aed1362845e1908053c0e3263cdb15a9708bdcb3a87beb386f75
|
| 3 |
+
size 8290737664
|
model-00002-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:17df0064383fe3ba8c37722f039980dac30a6cbbdd939619cea3b1e950c92768
|
| 3 |
+
size 2960456136
|
model-00003-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d8cbc95720f20119e7c40b0e0d5f310ce810050ef3010c0b6d65dd83848dfa52
|
| 3 |
+
size 2960456840
|
model-00004-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1c9b5241a437e4c9580e4d0664270f6a4ce6afc657bd4ec3e20c5d8516b2b1c1
|
| 3 |
+
size 3013558976
|
model-00005-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:cd88b89f5e937ec9828e7c2b7b070a427858e3714aee1c36bf71ecccbe192f8a
|
| 3 |
+
size 2960456136
|
model-00006-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8fca172022f97e65869e518c0844807b747dc5054da828e0a4eb29ef893dff32
|
| 3 |
+
size 2960462128
|
model-00007-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:17b8b580df7429d3098bfd1227f9640fd379402c611dcc4d26be8caf94436cd8
|
| 3 |
+
size 2960464864
|
model-00008-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:66981b6fa4e5b32537fa73d7b80524b3e9da98ce21ccdb8cd25844bf9aca4b0a
|
| 3 |
+
size 3013567152
|
model-00009-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:50d2b6296ba45deb6e5d8d41b8d2d9d5ae9322716797c9c990338a37bd478a06
|
| 3 |
+
size 2960464160
|
model-00010-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:de68a392f51f15ccd9a7c025c0123d8c8eab0a17be7d9c247771bd878474286d
|
| 3 |
+
size 2960464160
|
model-00011-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4596eea10d973426e31d8fbccd012ec0af2a3cc30f79546a158022a8efa9aeb1
|
| 3 |
+
size 2960464864
|
model-00012-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d6c915d7c51d4f1f828cb17d6ce31e524a0f4209333f6e62516add0a5ab21e20
|
| 3 |
+
size 3013567152
|
model-00013-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3f6e0d03bb88c02167904cc6158ad68e3e4dac1f44ea60a2edbd5406c4273eb
|
| 3 |
+
size 2960464160
|
model-00014-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:aaee8a414a8a2495390a18961809b2937af66da9af85e78d866fa3318e461770
|
| 3 |
+
size 2960464160
|
model-00015-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4b807748938cdaacfd9bf20df81fec4d68bdb78ada728955e9c577b46973222f
|
| 3 |
+
size 2960464864
|
model-00016-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:633ff3df85d9a0ad986fc223ab51d80b530c4afdb597a4a33ddc21d9ebf7528b
|
| 3 |
+
size 3013567152
|
model-00017-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7285459e671e76c0658d228a67ca6eac0c2455a61bf730cc82ecbcab4564716f
|
| 3 |
+
size 2960464160
|
model-00018-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fb3a72814336d863aea0449f8553b50b3077805d8d85994793a6b78548cfa737
|
| 3 |
+
size 2960464160
|
model-00019-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e84a9fbce9923b035fdbb644cc7eb7aaf9213ce56da5cff15495d64a24db1fde
|
| 3 |
+
size 2960464864
|
model-00020-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c8bc99d20554ec2006f7247c5ecf9518dec0eafb3604f51e4a59729b0315470c
|
| 3 |
+
size 3013567152
|
model-00021-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1d9c34978ca2cd6f49ef3839494bd96004cd384a54f9557966f0d2b57eb2307e
|
| 3 |
+
size 2960464160
|
model-00022-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ce3a4734623538bb7a96a30ed9b7fac7d1b00c1f259118ffad9bef791329bc83
|
| 3 |
+
size 2960464160
|
model-00023-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:183e8939916fff225e4d658f8c133d5f3021319dd8414658e5a058164beeefd9
|
| 3 |
+
size 2960464864
|
model-00024-of-00024.safetensors
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:504fb40910f872b84692923115b56d9502b1381c5a8c295add35dd4d624a05f4
|
| 3 |
+
size 7666257952
|
model.safetensors.index.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:94e24dbc10649edad8909f6d91448616ddbba5318a83a6d05454a244df3b2a30
|
| 3 |
+
size 18563389
|
modeling_bailing_moe_v3.py
ADDED
|
@@ -0,0 +1,1625 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2025 Antgroup and The HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
|
| 5 |
+
# and OPT implementations in this library. It has been modified from its
|
| 6 |
+
# original forms to accommodate minor architectural differences compared
|
| 7 |
+
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
|
| 8 |
+
#
|
| 9 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
+
# you may not use this file except in compliance with the License.
|
| 11 |
+
# You may obtain a copy of the License at
|
| 12 |
+
#
|
| 13 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 14 |
+
#
|
| 15 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 16 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 17 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
+
# See the License for the specific language governing permissions and
|
| 19 |
+
# limitations under the License.
|
| 20 |
+
"""PyTorch BailingMoE model."""
|
| 21 |
+
|
| 22 |
+
import math
|
| 23 |
+
import warnings
|
| 24 |
+
from typing import List, Optional, Tuple, Union, Callable
|
| 25 |
+
from copy import deepcopy
|
| 26 |
+
|
| 27 |
+
import torch
|
| 28 |
+
import torch.nn.functional as F
|
| 29 |
+
from torch import nn
|
| 30 |
+
|
| 31 |
+
from transformers.activations import ACT2FN
|
| 32 |
+
from transformers.cache_utils import Cache, DynamicCache
|
| 33 |
+
from transformers.modeling_attn_mask_utils import (
|
| 34 |
+
AttentionMaskConverter,
|
| 35 |
+
_prepare_4d_attention_mask,
|
| 36 |
+
_prepare_4d_causal_attention_mask,
|
| 37 |
+
_prepare_4d_causal_attention_mask_for_sdpa,
|
| 38 |
+
)
|
| 39 |
+
from transformers.modeling_outputs import MoeModelOutputWithPast
|
| 40 |
+
from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
|
| 41 |
+
from transformers.modeling_utils import PreTrainedModel
|
| 42 |
+
from transformers.pytorch_utils import ALL_LAYERNORM_LAYERS, is_torch_greater_or_equal_than_1_13
|
| 43 |
+
from transformers.utils import (
|
| 44 |
+
add_start_docstrings,
|
| 45 |
+
add_start_docstrings_to_model_forward,
|
| 46 |
+
logging,
|
| 47 |
+
replace_return_docstrings,
|
| 48 |
+
)
|
| 49 |
+
from transformers.utils.import_utils import is_torch_fx_available
|
| 50 |
+
from .configuration_bailing_moe_v3 import BailingMoeV3Config
|
| 51 |
+
from transformers.generation.utils import GenerationMixin
|
| 52 |
+
from dataclasses import dataclass
|
| 53 |
+
from transformers.utils import ModelOutput
|
| 54 |
+
from transformers import DynamicLayer
|
| 55 |
+
from transformers.processing_utils import Unpack
|
| 56 |
+
from transformers.utils import TransformersKwargs
|
| 57 |
+
from transformers.utils.deprecation import deprecate_kwarg
|
| 58 |
+
from transformers.modeling_flash_attention_utils import FlashAttentionKwargs
|
| 59 |
+
|
| 60 |
+
from fla.ops.simple_gla.fused_recurrent import fused_recurrent_simple_gla
|
| 61 |
+
from fla.ops.simple_gla.chunk import chunk_simple_gla
|
| 62 |
+
from einops import rearrange, repeat
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
try:
|
| 66 |
+
from fla.modules import FusedRMSNormGated, ShortConvolution
|
| 67 |
+
from fla.ops.kda import chunk_kda, fused_recurrent_kda
|
| 68 |
+
|
| 69 |
+
from fla.ops.utils.index import prepare_cu_seqlens_from_mask, prepare_lens_from_mask
|
| 70 |
+
from fla.utils import tensor_cache
|
| 71 |
+
except ImportError:
|
| 72 |
+
raise ImportError("Plese run `pip install -U fla-core`")
|
| 73 |
+
|
| 74 |
+
# This makes `_prepare_4d_causal_attention_mask` a leaf function in the FX graph.
|
| 75 |
+
# It means that the function will not be traced through and simply appear as a node in the graph.
|
| 76 |
+
if is_torch_fx_available():
|
| 77 |
+
if not is_torch_greater_or_equal_than_1_13:
|
| 78 |
+
import torch.fx
|
| 79 |
+
|
| 80 |
+
_prepare_4d_causal_attention_mask = torch.fx.wrap(_prepare_4d_causal_attention_mask)
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
logger = logging.get_logger(__name__)
|
| 84 |
+
|
| 85 |
+
_CONFIG_FOR_DOC = "BailingMoeV3Config"
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def roll_tensor(tensor, shifts=-1, dims=-1, fill_value=0):
|
| 89 |
+
"""Roll the tensor input along the given dimension(s).
|
| 90 |
+
Inserted elements are set to be 0.0.
|
| 91 |
+
"""
|
| 92 |
+
rolled_tensor = torch.roll(tensor, shifts=shifts, dims=dims)
|
| 93 |
+
rolled_tensor.select(dims, shifts).fill_(fill_value)
|
| 94 |
+
return rolled_tensor, rolled_tensor.sum()
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
@dataclass
|
| 98 |
+
class MoEV3CausalLMOutputWithPast(ModelOutput):
|
| 99 |
+
"""
|
| 100 |
+
Base class for causal language model (or autoregressive) outputs as well as Mixture of Expert's router hidden
|
| 101 |
+
states terms, to train a MoE model.
|
| 102 |
+
Args:
|
| 103 |
+
loss (`torch.FloatTensor` of shape `(1,)`, *optional*, returned when `labels` is provided):
|
| 104 |
+
Language modeling loss (for next-token prediction).
|
| 105 |
+
logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`):
|
| 106 |
+
Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax).
|
| 107 |
+
past_key_values (`Cache`, *optional*, returned when `use_cache=True` is passed or when `config.use_cache=True`):
|
| 108 |
+
It is a [`~cache_utils.Cache`] instance. For more details, see our [kv cache guide](https://huggingface.co/docs/transformers/en/kv_cache).
|
| 109 |
+
Contains pre-computed hidden-states (key and values in the self-attention blocks) that can be used (see
|
| 110 |
+
`past_key_values` input) to speed up sequential decoding.
|
| 111 |
+
hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`):
|
| 112 |
+
Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, +
|
| 113 |
+
one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`.
|
| 114 |
+
Hidden-states of the model at the output of each layer plus the optional initial embedding outputs.
|
| 115 |
+
attentions (`tuple(torch.FloatTensor)`, *optional*, returned when `output_attentions=True` is passed or when `config.output_attentions=True`):
|
| 116 |
+
Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, num_heads, sequence_length,
|
| 117 |
+
sequence_length)`.
|
| 118 |
+
Attentions weights after the attention softmax, used to compute the weighted average in the self-attention
|
| 119 |
+
heads.
|
| 120 |
+
z_loss (`torch.FloatTensor`, *optional*, returned when `labels` is provided):
|
| 121 |
+
z_loss for the sparse modules.
|
| 122 |
+
aux_loss (`torch.FloatTensor`, *optional*, returned when `labels` is provided):
|
| 123 |
+
aux_loss for the sparse modules.
|
| 124 |
+
router_logits (`tuple(torch.FloatTensor)`, *optional*, returned when `output_router_logits=True` is passed or when `config.add_router_probs=True`):
|
| 125 |
+
Tuple of `torch.FloatTensor` (one for each layer) of shape `(batch_size, sequence_length, num_experts)`.
|
| 126 |
+
Router logits of the encoder model, useful to compute the auxiliary loss and the z_loss for the sparse
|
| 127 |
+
modules.
|
| 128 |
+
"""
|
| 129 |
+
|
| 130 |
+
loss: Optional[torch.FloatTensor] = None
|
| 131 |
+
logits: Optional[torch.FloatTensor] = None
|
| 132 |
+
past_key_values: Optional[Cache] = None
|
| 133 |
+
hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None
|
| 134 |
+
attentions: Optional[tuple[torch.FloatTensor, ...]] = None
|
| 135 |
+
z_loss: Optional[torch.FloatTensor] = None
|
| 136 |
+
aux_loss: Optional[torch.FloatTensor] = None
|
| 137 |
+
router_logits: Optional[tuple[torch.FloatTensor]] = None
|
| 138 |
+
mtp_loss: Optional[torch.FloatTensor] = None
|
| 139 |
+
mtp_logits: Optional[tuple[torch.FloatTensor, ...]] = None
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
class MoeV3ModelOutputWithPast(MoeModelOutputWithPast):
|
| 143 |
+
|
| 144 |
+
def __init__(self, mtp_hidden_states=None, **kwargs):
|
| 145 |
+
super().__init__(**kwargs)
|
| 146 |
+
self.mtp_hidden_states = mtp_hidden_states
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def index_first_axis(x, indices):
|
| 150 |
+
other_shape = x.shape[1:]
|
| 151 |
+
second_dim = other_shape.numel()
|
| 152 |
+
return torch.gather(
|
| 153 |
+
rearrange(x, "b ... -> b (...)"),
|
| 154 |
+
0,
|
| 155 |
+
repeat(indices, "z -> z d", d=second_dim),
|
| 156 |
+
).reshape(-1, *other_shape)
|
| 157 |
+
|
| 158 |
+
|
| 159 |
+
def index_put_first_axis(x, indices, first_axis_dim):
|
| 160 |
+
y = torch.zeros(first_axis_dim, *x.shape[1:], device=x.device, dtype=x.dtype)
|
| 161 |
+
y[indices] = x
|
| 162 |
+
# y.scatter_(0, repeat(indices, 'z -> z d', d=x.shape[1]), x)
|
| 163 |
+
return y
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
def pad_input(
|
| 167 |
+
hidden_states: torch.Tensor,
|
| 168 |
+
indices: torch.LongTensor,
|
| 169 |
+
batch_size: int,
|
| 170 |
+
seq_len: int,
|
| 171 |
+
) -> torch.Tensor:
|
| 172 |
+
output = index_put_first_axis(hidden_states, indices, batch_size * seq_len)
|
| 173 |
+
return rearrange(output, "(b s) ... -> b s ...", b=batch_size)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
@tensor_cache
|
| 177 |
+
def _get_unpad_data(attention_mask):
|
| 178 |
+
seqlens_in_batch = attention_mask.sum(dim=-1, dtype=torch.int32)
|
| 179 |
+
indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
|
| 180 |
+
max_seqlen_in_batch = seqlens_in_batch.max().item()
|
| 181 |
+
cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0))
|
| 182 |
+
return (
|
| 183 |
+
indices,
|
| 184 |
+
cu_seqlens,
|
| 185 |
+
max_seqlen_in_batch,
|
| 186 |
+
)
|
| 187 |
+
|
| 188 |
+
|
| 189 |
+
def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
|
| 190 |
+
warnings.warn(
|
| 191 |
+
"Calling `transformers.models.BailingMoeV3.modeling_BailingMoeV3._prepare_4d_attention_mask` is deprecated and will be removed in v4.37. Use `transformers.modeling_attn_mask_utils._prepare_4d_attention_mask"
|
| 192 |
+
)
|
| 193 |
+
return _prepare_4d_attention_mask(mask=mask, dtype=dtype, tgt_len=tgt_len)
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
def _make_causal_mask(
|
| 197 |
+
input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0
|
| 198 |
+
):
|
| 199 |
+
warnings.warn(
|
| 200 |
+
"Calling `transformers.models.BailingMoeV3.modeling_BailingMoeV3._make_causal_mask` is deprecated and will be removed in v4.37. Use `transformers.models.BailingMoeV3.modeling_BailingMoeV3.AttentionMaskConverter._make_causal_mask"
|
| 201 |
+
)
|
| 202 |
+
return AttentionMaskConverter._make_causal_mask(
|
| 203 |
+
input_ids_shape=input_ids_shape, dtype=dtype, device=device, past_key_values_length=past_key_values_length
|
| 204 |
+
)
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
class BailingMoeV3RMSNorm(nn.Module):
|
| 208 |
+
def __init__(self, hidden_size, eps=1e-6):
|
| 209 |
+
"""
|
| 210 |
+
BailingMoeV3RMSNorm is equivalent to T5LayerNorm
|
| 211 |
+
"""
|
| 212 |
+
super().__init__()
|
| 213 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 214 |
+
self.variance_epsilon = eps
|
| 215 |
+
|
| 216 |
+
def forward(self, hidden_states):
|
| 217 |
+
input_dtype = hidden_states.dtype
|
| 218 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 219 |
+
variance = hidden_states.pow(2).mean(-1, keepdim=True)
|
| 220 |
+
hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
|
| 221 |
+
return self.weight * hidden_states.to(input_dtype)
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
class BailingMoeV3GroupRMSNorm(nn.Module):
|
| 225 |
+
def __init__(self, hidden_size, group_norm_size, eps=1e-6):
|
| 226 |
+
"""
|
| 227 |
+
BailingMoeV3RMSNorm is equivalent to T5LayerNorm
|
| 228 |
+
"""
|
| 229 |
+
super().__init__()
|
| 230 |
+
self.weight = nn.Parameter(torch.ones(hidden_size))
|
| 231 |
+
self.group_norm_size = group_norm_size
|
| 232 |
+
assert hidden_size % group_norm_size == 0, "hidden_size must be divisible by group_norm_size"
|
| 233 |
+
self.variance_epsilon = eps
|
| 234 |
+
|
| 235 |
+
def forward(self, hidden_states):
|
| 236 |
+
input_dtype = hidden_states.dtype
|
| 237 |
+
input_shape = hidden_states.size()
|
| 238 |
+
group_input_shape = input_shape[:-1] + (self.group_norm_size, input_shape[-1] // self.group_norm_size)
|
| 239 |
+
hidden_states = hidden_states.view(group_input_shape)
|
| 240 |
+
hidden_states = hidden_states.to(torch.float32)
|
| 241 |
+
variance = hidden_states.pow(2).mean(-1, keepdim=True)
|
| 242 |
+
hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)
|
| 243 |
+
return self.weight * hidden_states.to(input_dtype).view(input_shape)
|
| 244 |
+
|
| 245 |
+
|
| 246 |
+
ALL_LAYERNORM_LAYERS.append(BailingMoeV3RMSNorm)
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
class BailingMoeV3RotaryEmbedding(nn.Module):
|
| 250 |
+
def __init__(self, config: BailingMoeV3Config, device=None):
|
| 251 |
+
super().__init__()
|
| 252 |
+
# BC: "rope_type" was originally "type"
|
| 253 |
+
if hasattr(config, "rope_scaling") and config.rope_scaling is not None:
|
| 254 |
+
self.rope_type = config.rope_scaling.get("rope_type", config.rope_scaling.get("type"))
|
| 255 |
+
else:
|
| 256 |
+
self.rope_type = "default"
|
| 257 |
+
self.max_seq_len_cached = config.max_position_embeddings
|
| 258 |
+
self.original_max_seq_len = config.max_position_embeddings
|
| 259 |
+
|
| 260 |
+
self.config = deepcopy(config)
|
| 261 |
+
self.config.head_dim = config.qk_rope_head_dim
|
| 262 |
+
self.config.partial_rotary_factor = 1.0
|
| 263 |
+
self.rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
|
| 264 |
+
|
| 265 |
+
inv_freq, self.attention_scaling = self.rope_init_fn(self.config, device)
|
| 266 |
+
self.register_buffer("inv_freq", inv_freq, persistent=False)
|
| 267 |
+
self.original_inv_freq = self.inv_freq
|
| 268 |
+
|
| 269 |
+
@torch.no_grad()
|
| 270 |
+
@dynamic_rope_update # power user: used with advanced RoPE types (e.g. dynamic rope)
|
| 271 |
+
def forward(self, x, position_ids):
|
| 272 |
+
inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
|
| 273 |
+
position_ids_expanded = position_ids[:, None, :].float()
|
| 274 |
+
|
| 275 |
+
device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
|
| 276 |
+
with torch.autocast(device_type=device_type, enabled=False): # Force float32
|
| 277 |
+
freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
|
| 278 |
+
emb = torch.cat((freqs, freqs), dim=-1)
|
| 279 |
+
cos = emb.cos() * self.attention_scaling
|
| 280 |
+
sin = emb.sin() * self.attention_scaling
|
| 281 |
+
|
| 282 |
+
return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
# Copied from transformers.models.llama.modeling_llama.rotate_half
|
| 286 |
+
def rotate_half(x):
|
| 287 |
+
"""Rotates half the hidden dims of the input."""
|
| 288 |
+
x1 = x[..., : x.shape[-1] // 2]
|
| 289 |
+
x2 = x[..., x.shape[-1] // 2 :]
|
| 290 |
+
return torch.cat((-x2, x1), dim=-1)
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
# Copied from transformers.models.llama.modeling_llama.apply_rotary_pos_emb
|
| 294 |
+
def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
|
| 295 |
+
"""Applies Rotary Position Embedding to the query and key tensors.
|
| 296 |
+
Args:
|
| 297 |
+
q (`torch.Tensor`): The query tensor.
|
| 298 |
+
k (`torch.Tensor`): The key tensor.
|
| 299 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 300 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 301 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 302 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 303 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 304 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 305 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 306 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 307 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 308 |
+
Returns:
|
| 309 |
+
`tuple(torch.Tensor)` comprising the query and key tensors rotated using the Rotary Position Embedding.
|
| 310 |
+
"""
|
| 311 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 312 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 313 |
+
|
| 314 |
+
# Keep half or full tensor for later concatenation
|
| 315 |
+
rotary_dim = cos.shape[-1]
|
| 316 |
+
q_rot, q_pass = q[..., :rotary_dim], q[..., rotary_dim:]
|
| 317 |
+
k_rot, k_pass = k[..., :rotary_dim], k[..., rotary_dim:]
|
| 318 |
+
|
| 319 |
+
# Apply rotary embeddings on the first half or full tensor
|
| 320 |
+
q_embed = (q_rot * cos) + (rotate_half(q_rot) * sin)
|
| 321 |
+
k_embed = (k_rot * cos) + (rotate_half(k_rot) * sin)
|
| 322 |
+
|
| 323 |
+
# Concatenate back to full shape
|
| 324 |
+
q_embed = torch.cat([q_embed, q_pass], dim=-1)
|
| 325 |
+
k_embed = torch.cat([k_embed, k_pass], dim=-1)
|
| 326 |
+
return q_embed, k_embed
|
| 327 |
+
|
| 328 |
+
|
| 329 |
+
class BailingMoeV3MLP(nn.Module):
|
| 330 |
+
def __init__(self, config: BailingMoeV3Config, intermediate_size: int):
|
| 331 |
+
super().__init__()
|
| 332 |
+
self.config = config
|
| 333 |
+
self.hidden_size = config.hidden_size
|
| 334 |
+
self.intermediate_size = intermediate_size
|
| 335 |
+
|
| 336 |
+
self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 337 |
+
self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
|
| 338 |
+
self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
|
| 339 |
+
self.act_fn = ACT2FN[config.hidden_act]
|
| 340 |
+
|
| 341 |
+
def forward(self, x):
|
| 342 |
+
return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
class BailingMoeV3Gate(nn.Module):
|
| 346 |
+
def __init__(self, config):
|
| 347 |
+
super().__init__()
|
| 348 |
+
self.config = config
|
| 349 |
+
self.top_k = config.num_experts_per_tok
|
| 350 |
+
self.num_experts = config.num_experts
|
| 351 |
+
|
| 352 |
+
self.n_group = config.n_group
|
| 353 |
+
self.topk_group = config.topk_group
|
| 354 |
+
|
| 355 |
+
# topk selection algorithm
|
| 356 |
+
self.gating_dim = config.hidden_size
|
| 357 |
+
self.weight = nn.Parameter(torch.empty((self.num_experts, self.gating_dim)))
|
| 358 |
+
self.routed_scaling_factor = config.routed_scaling_factor
|
| 359 |
+
|
| 360 |
+
self.register_buffer("expert_bias", torch.zeros((self.num_experts)))
|
| 361 |
+
self.reset_parameters()
|
| 362 |
+
|
| 363 |
+
def reset_parameters(self) -> None:
|
| 364 |
+
import torch.nn.init as init
|
| 365 |
+
|
| 366 |
+
init.kaiming_uniform_(self.weight, a=math.sqrt(5))
|
| 367 |
+
|
| 368 |
+
def group_limited_topk(
|
| 369 |
+
self,
|
| 370 |
+
scores: torch.Tensor,
|
| 371 |
+
):
|
| 372 |
+
num_tokens, _ = scores.size()
|
| 373 |
+
# Organize the experts into groups
|
| 374 |
+
group_scores = scores.view(num_tokens, self.n_group, -1).topk(2, dim=-1)[0].sum(dim=-1)
|
| 375 |
+
group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1]
|
| 376 |
+
group_mask = torch.zeros_like(group_scores)
|
| 377 |
+
group_mask.scatter_(1, group_idx, 1)
|
| 378 |
+
|
| 379 |
+
# Mask the experts based on selection groups
|
| 380 |
+
score_mask = (
|
| 381 |
+
group_mask.unsqueeze(-1)
|
| 382 |
+
.expand(num_tokens, self.n_group, self.num_experts // self.n_group)
|
| 383 |
+
.reshape(num_tokens, -1)
|
| 384 |
+
)
|
| 385 |
+
|
| 386 |
+
masked_scores = scores.masked_fill(~score_mask.bool(), float('-inf'))
|
| 387 |
+
probs, top_indices = torch.topk(masked_scores, k=self.top_k, dim=-1)
|
| 388 |
+
|
| 389 |
+
return probs, top_indices
|
| 390 |
+
|
| 391 |
+
def forward(self, hidden_states):
|
| 392 |
+
# compute gating score
|
| 393 |
+
hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
|
| 394 |
+
logits = F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32))
|
| 395 |
+
|
| 396 |
+
scores = torch.sigmoid(logits.float()).type_as(logits)
|
| 397 |
+
|
| 398 |
+
scores_for_routing = scores + self.expert_bias
|
| 399 |
+
_, topk_idx = self.group_limited_topk(scores_for_routing)
|
| 400 |
+
|
| 401 |
+
scores = torch.gather(scores, dim=1, index=topk_idx).type_as(logits)
|
| 402 |
+
|
| 403 |
+
topk_weight = scores / (scores.sum(dim=-1, keepdim=True) + 1e-20) if self.top_k > 1 else scores
|
| 404 |
+
topk_weight = topk_weight * self.routed_scaling_factor
|
| 405 |
+
|
| 406 |
+
return topk_idx, topk_weight, logits
|
| 407 |
+
|
| 408 |
+
|
| 409 |
+
class BailingMoeV3SparseMoeBlock(nn.Module):
|
| 410 |
+
"""
|
| 411 |
+
A mixed expert module containing shared experts.
|
| 412 |
+
"""
|
| 413 |
+
|
| 414 |
+
def __init__(self, config: BailingMoeV3Config):
|
| 415 |
+
super().__init__()
|
| 416 |
+
self.config = config
|
| 417 |
+
self.num_experts_per_tok = config.num_experts_per_tok
|
| 418 |
+
self._setup_experts()
|
| 419 |
+
self.gate = BailingMoeV3Gate(config)
|
| 420 |
+
if config.num_shared_experts is not None:
|
| 421 |
+
self.shared_experts = BailingMoeV3MLP(
|
| 422 |
+
config=config, intermediate_size=config.moe_shared_expert_intermediate_size * config.num_shared_experts
|
| 423 |
+
)
|
| 424 |
+
|
| 425 |
+
def _setup_experts(self):
|
| 426 |
+
self.experts = nn.ModuleList(
|
| 427 |
+
[
|
| 428 |
+
BailingMoeV3MLP(config=self.config, intermediate_size=self.config.moe_intermediate_size)
|
| 429 |
+
for _ in range(self.config.num_experts)
|
| 430 |
+
]
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
+
def forward(self, hidden_states):
|
| 434 |
+
identity = hidden_states
|
| 435 |
+
bsz, seq_len, h = hidden_states.shape
|
| 436 |
+
topk_idx, topk_weight, router_logits = self.gate(hidden_states)
|
| 437 |
+
hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
|
| 438 |
+
flat_topk_idx = topk_idx.view(-1)
|
| 439 |
+
if self.training:
|
| 440 |
+
hidden_states = hidden_states.repeat_interleave(self.num_experts_per_tok, dim=0)
|
| 441 |
+
y = torch.empty_like(hidden_states)
|
| 442 |
+
for i, expert in enumerate(self.experts):
|
| 443 |
+
y[flat_topk_idx == i] = expert(hidden_states[flat_topk_idx == i])
|
| 444 |
+
y = (y.view(*topk_weight.shape, -1) * topk_weight.unsqueeze(-1)).sum(dim=1)
|
| 445 |
+
y = y.to(hidden_states.dtype).view(bsz, seq_len, h)
|
| 446 |
+
else:
|
| 447 |
+
y = self.moe_infer(hidden_states, topk_idx, topk_weight).view(bsz, seq_len, h)
|
| 448 |
+
if self.config.num_shared_experts is not None:
|
| 449 |
+
y = y + self.shared_experts(identity)
|
| 450 |
+
return y, (router_logits.view(bsz, seq_len, -1), topk_idx.view(bsz, seq_len, -1))
|
| 451 |
+
|
| 452 |
+
@torch.no_grad()
|
| 453 |
+
def moe_infer(self, x, topk_ids, topk_weight):
|
| 454 |
+
cnts = topk_ids.new_zeros((topk_ids.shape[0], len(self.experts)))
|
| 455 |
+
cnts.scatter_(1, topk_ids, 1)
|
| 456 |
+
tokens_per_expert = cnts.sum(dim=0)
|
| 457 |
+
idxs = topk_ids.view(-1).argsort()
|
| 458 |
+
sorted_tokens = x[idxs // topk_ids.shape[1]]
|
| 459 |
+
tokens_per_expert = tokens_per_expert.cpu().numpy()
|
| 460 |
+
outputs = []
|
| 461 |
+
start_idx = 0
|
| 462 |
+
for i, num_tokens in enumerate(tokens_per_expert):
|
| 463 |
+
end_idx = start_idx + num_tokens
|
| 464 |
+
if num_tokens == 0:
|
| 465 |
+
continue
|
| 466 |
+
expert = self.experts[i]
|
| 467 |
+
tokens_for_this_expert = sorted_tokens[start_idx:end_idx]
|
| 468 |
+
expert_out = expert(tokens_for_this_expert)
|
| 469 |
+
outputs.append(expert_out.to(x.device))
|
| 470 |
+
start_idx = end_idx
|
| 471 |
+
|
| 472 |
+
outs = torch.cat(outputs, dim=0) if len(outputs) else sorted_tokens.new_empty(0)
|
| 473 |
+
new_x = torch.empty_like(outs)
|
| 474 |
+
new_x[idxs] = outs
|
| 475 |
+
final_out = (
|
| 476 |
+
new_x.view(*topk_ids.shape, -1)
|
| 477 |
+
.type(topk_weight.dtype)
|
| 478 |
+
.mul_(topk_weight.unsqueeze(dim=-1))
|
| 479 |
+
.sum(dim=1)
|
| 480 |
+
.type(new_x.dtype)
|
| 481 |
+
)
|
| 482 |
+
return final_out
|
| 483 |
+
|
| 484 |
+
|
| 485 |
+
# Copied from transformers.models.llama.modeling_llama.repeat_kv
|
| 486 |
+
def repeat_kv(hidden_states: torch.Tensor, n_rep: int, head_first: bool = True) -> torch.Tensor:
|
| 487 |
+
"""
|
| 488 |
+
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). If head_first is True, the hidden states go from (batch,
|
| 489 |
+
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
|
| 490 |
+
"""
|
| 491 |
+
if n_rep == 1:
|
| 492 |
+
return hidden_states
|
| 493 |
+
if head_first:
|
| 494 |
+
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
|
| 495 |
+
hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
|
| 496 |
+
return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
|
| 497 |
+
else:
|
| 498 |
+
batch, slen, num_key_value_heads, head_dim = hidden_states.shape
|
| 499 |
+
hidden_states = hidden_states[:, :, :, None, :].expand(batch, slen, num_key_value_heads, n_rep, head_dim)
|
| 500 |
+
return hidden_states.reshape(batch, slen, num_key_value_heads * n_rep, head_dim)
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
def repeat_kv2(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
|
| 504 |
+
"""
|
| 505 |
+
This is the equivalent of torch.repeat_interleave(x, dim=1, repeats=n_rep). The hidden states go from (batch,
|
| 506 |
+
num_key_value_heads, seqlen, head_dim) to (batch, num_attention_heads, seqlen, head_dim)
|
| 507 |
+
"""
|
| 508 |
+
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
|
| 509 |
+
if n_rep == 1:
|
| 510 |
+
return hidden_states
|
| 511 |
+
hidden_states = hidden_states[:, :, None, :, :].expand(batch, num_key_value_heads, n_rep, slen, head_dim)
|
| 512 |
+
return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
|
| 513 |
+
|
| 514 |
+
|
| 515 |
+
def eager_attention_forward(
|
| 516 |
+
module: nn.Module,
|
| 517 |
+
query: torch.Tensor,
|
| 518 |
+
key: torch.Tensor,
|
| 519 |
+
value: torch.Tensor,
|
| 520 |
+
attention_mask: Optional[torch.Tensor],
|
| 521 |
+
scaling: float,
|
| 522 |
+
dropout: float = 0.0,
|
| 523 |
+
**kwargs: Unpack[TransformersKwargs],
|
| 524 |
+
):
|
| 525 |
+
key_states = repeat_kv2(key, module.num_key_value_groups)
|
| 526 |
+
value_states = repeat_kv2(value, module.num_key_value_groups)
|
| 527 |
+
|
| 528 |
+
attn_weights = torch.matmul(query, key_states.transpose(2, 3)) * scaling
|
| 529 |
+
if attention_mask is not None:
|
| 530 |
+
causal_mask = attention_mask[:, :, :, : key_states.shape[-2]]
|
| 531 |
+
attn_weights = attn_weights + causal_mask
|
| 532 |
+
|
| 533 |
+
attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query.dtype)
|
| 534 |
+
attn_weights = nn.functional.dropout(attn_weights, p=dropout, training=module.training)
|
| 535 |
+
attn_output = torch.matmul(attn_weights, value_states)
|
| 536 |
+
attn_output = attn_output.transpose(1, 2).contiguous()
|
| 537 |
+
|
| 538 |
+
return attn_output, attn_weights
|
| 539 |
+
|
| 540 |
+
|
| 541 |
+
def apply_rotary_pos_emb_interleave(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
|
| 542 |
+
r"""
|
| 543 |
+
TODO let's just use the original freqcis computation to not have the view
|
| 544 |
+
transpose + reshape! This is not optimized!
|
| 545 |
+
Applies Rotary Position Embedding to the query and key tensors.
|
| 546 |
+
|
| 547 |
+
Args:
|
| 548 |
+
q (`torch.Tensor`): The query tensor.
|
| 549 |
+
k (`torch.Tensor`): The key tensor.
|
| 550 |
+
cos (`torch.Tensor`): The cosine part of the rotary embedding.
|
| 551 |
+
sin (`torch.Tensor`): The sine part of the rotary embedding.
|
| 552 |
+
position_ids (`torch.Tensor`):
|
| 553 |
+
The position indices of the tokens corresponding to the query and key tensors. For example, this can be
|
| 554 |
+
used to pass offsetted position ids when working with a KV-cache.
|
| 555 |
+
unsqueeze_dim (`int`, *optional*, defaults to 1):
|
| 556 |
+
The 'unsqueeze_dim' argument specifies the dimension along which to unsqueeze cos[position_ids] and
|
| 557 |
+
sin[position_ids] so that they can be properly broadcasted to the dimensions of q and k. For example, note
|
| 558 |
+
that cos[position_ids] and sin[position_ids] have the shape [batch_size, seq_len, head_dim]. Then, if q and
|
| 559 |
+
k have the shape [batch_size, heads, seq_len, head_dim], then setting unsqueeze_dim=1 makes
|
| 560 |
+
cos[position_ids] and sin[position_ids] broadcastable to the shapes of q and k. Similarly, if q and k have
|
| 561 |
+
the shape [batch_size, seq_len, heads, head_dim], then set unsqueeze_dim=2.
|
| 562 |
+
Returns:
|
| 563 |
+
`tuple(torch.Tensor)` comprising of the query and key tensors rotated using the Rotary Position Embedding.
|
| 564 |
+
"""
|
| 565 |
+
cos = cos.unsqueeze(unsqueeze_dim)
|
| 566 |
+
sin = sin.unsqueeze(unsqueeze_dim)
|
| 567 |
+
|
| 568 |
+
b, h, s, d = q.shape
|
| 569 |
+
q = q.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
|
| 570 |
+
|
| 571 |
+
b, h, s, d = k.shape
|
| 572 |
+
k = k.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
|
| 573 |
+
|
| 574 |
+
q_embed = (q * cos) + (rotate_half(q) * sin)
|
| 575 |
+
k_embed = (k * cos) + (rotate_half(k) * sin)
|
| 576 |
+
return q_embed, k_embed
|
| 577 |
+
|
| 578 |
+
|
| 579 |
+
def yarn_get_mscale(scale=1, mscale=1):
|
| 580 |
+
if scale <= 1:
|
| 581 |
+
return 1.0
|
| 582 |
+
return 0.1 * mscale * math.log(scale) + 1.0
|
| 583 |
+
|
| 584 |
+
|
| 585 |
+
class BailingMoeV3MultiLatentAttention(nn.Module):
|
| 586 |
+
"""Multi-headed attention from 'Attention Is All You Need' paper"""
|
| 587 |
+
|
| 588 |
+
def __init__(self, config: BailingMoeV3Config, layer_idx: int):
|
| 589 |
+
super().__init__()
|
| 590 |
+
self.config = config
|
| 591 |
+
self.layer_idx = layer_idx
|
| 592 |
+
self.num_key_value_groups = config.num_attention_heads // config.num_key_value_heads
|
| 593 |
+
self.attention_dropout = config.attention_dropout
|
| 594 |
+
self.num_heads = config.num_attention_heads
|
| 595 |
+
self.rope_theta = config.rope_theta
|
| 596 |
+
self.q_lora_rank = config.q_lora_rank
|
| 597 |
+
self.qk_rope_head_dim = config.qk_rope_head_dim
|
| 598 |
+
self.kv_lora_rank = config.kv_lora_rank
|
| 599 |
+
self.v_head_dim = config.v_head_dim
|
| 600 |
+
self.qk_nope_head_dim = config.qk_nope_head_dim
|
| 601 |
+
self.qk_head_dim = config.qk_head_dim
|
| 602 |
+
self.gated_attention_proj_granularity_type = config.gated_attention_proj_granularity_type
|
| 603 |
+
|
| 604 |
+
self.is_causal = True
|
| 605 |
+
if self.q_lora_rank is None:
|
| 606 |
+
self.q_proj = nn.Linear(config.hidden_size, self.num_heads * self.qk_head_dim, bias=False)
|
| 607 |
+
else:
|
| 608 |
+
self.q_a_proj = nn.Linear(config.hidden_size, config.q_lora_rank, bias=config.use_qkv_bias)
|
| 609 |
+
self.q_a_layernorm = BailingMoeV3RMSNorm(config.q_lora_rank)
|
| 610 |
+
self.q_b_proj = nn.Linear(config.q_lora_rank, self.num_heads * self.qk_head_dim, bias=False)
|
| 611 |
+
|
| 612 |
+
self.kv_a_proj_with_mqa = nn.Linear(
|
| 613 |
+
config.hidden_size,
|
| 614 |
+
self.kv_lora_rank + self.qk_rope_head_dim,
|
| 615 |
+
bias=config.use_qkv_bias,
|
| 616 |
+
)
|
| 617 |
+
self.kv_a_layernorm = BailingMoeV3RMSNorm(self.kv_lora_rank)
|
| 618 |
+
self.kv_b_proj = nn.Linear(
|
| 619 |
+
self.kv_lora_rank,
|
| 620 |
+
self.num_heads * (self.qk_nope_head_dim + self.v_head_dim),
|
| 621 |
+
bias=False,
|
| 622 |
+
)
|
| 623 |
+
if self.gated_attention_proj_granularity_type is None:
|
| 624 |
+
self.g_proj = None
|
| 625 |
+
elif self.gated_attention_proj_granularity_type == "head_wise":
|
| 626 |
+
self.g_proj = nn.Linear(config.hidden_size, self.num_heads, bias=False)
|
| 627 |
+
elif self.gated_attention_proj_granularity_type == "element_wise":
|
| 628 |
+
self.g_proj = nn.Linear(config.hidden_size, self.num_heads * self.v_head_dim, bias=False)
|
| 629 |
+
|
| 630 |
+
self.dense = nn.Linear(
|
| 631 |
+
self.num_heads * self.v_head_dim,
|
| 632 |
+
config.hidden_size,
|
| 633 |
+
bias=config.use_qkv_bias,
|
| 634 |
+
)
|
| 635 |
+
|
| 636 |
+
self.scaling = self.qk_head_dim ** (-0.5)
|
| 637 |
+
if self.config.rope_scaling is not None:
|
| 638 |
+
mscale_all_dim = self.config.rope_scaling.get("mscale_all_dim", 0)
|
| 639 |
+
scaling_factor = self.config.rope_scaling["factor"]
|
| 640 |
+
if mscale_all_dim:
|
| 641 |
+
mscale = yarn_get_mscale(scaling_factor, mscale_all_dim)
|
| 642 |
+
self.scaling = self.scaling * mscale * mscale
|
| 643 |
+
|
| 644 |
+
@deprecate_kwarg("past_key_value", new_name="past_key_values", version="4.58")
|
| 645 |
+
def forward(
|
| 646 |
+
self,
|
| 647 |
+
hidden_states: torch.Tensor,
|
| 648 |
+
position_embeddings: tuple[torch.Tensor, torch.Tensor],
|
| 649 |
+
attention_mask: Optional[torch.Tensor],
|
| 650 |
+
past_key_values: Optional[Cache] = None,
|
| 651 |
+
cache_position: Optional[torch.LongTensor] = None,
|
| 652 |
+
**kwargs: Unpack[FlashAttentionKwargs],
|
| 653 |
+
) -> tuple[torch.Tensor, Optional[torch.Tensor], Optional[tuple[torch.Tensor]]]:
|
| 654 |
+
|
| 655 |
+
batch_size, seq_length = hidden_states.shape[:-1]
|
| 656 |
+
query_shape = (batch_size, seq_length, -1, self.qk_head_dim)
|
| 657 |
+
key_shape = (batch_size, seq_length, -1, self.qk_nope_head_dim + self.v_head_dim)
|
| 658 |
+
|
| 659 |
+
if self.q_lora_rank is None:
|
| 660 |
+
q_states = self.q_proj(hidden_states)
|
| 661 |
+
else:
|
| 662 |
+
q_states = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states)))
|
| 663 |
+
q_states = q_states.view(query_shape).transpose(1, 2)
|
| 664 |
+
q_pass, q_rot = torch.split(q_states, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1)
|
| 665 |
+
|
| 666 |
+
compressed_kv = self.kv_a_proj_with_mqa(hidden_states)
|
| 667 |
+
k_pass, k_rot = torch.split(compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1)
|
| 668 |
+
|
| 669 |
+
k_pass = self.kv_b_proj(self.kv_a_layernorm(k_pass)).view(key_shape).transpose(1, 2)
|
| 670 |
+
k_pass, value_states = torch.split(k_pass, [self.qk_nope_head_dim, self.v_head_dim], dim=-1)
|
| 671 |
+
|
| 672 |
+
k_rot = k_rot.view(batch_size, 1, seq_length, self.qk_rope_head_dim)
|
| 673 |
+
|
| 674 |
+
cos, sin = position_embeddings # tptest
|
| 675 |
+
if self.config.rope_interleave: # support using interleaved weights for efficiency
|
| 676 |
+
q_rot, k_rot = apply_rotary_pos_emb_interleave(q_rot, k_rot, cos, sin)
|
| 677 |
+
else:
|
| 678 |
+
x = 1 / 0
|
| 679 |
+
q_rot, k_rot = apply_rotary_pos_emb(q_rot, k_rot, cos, sin)
|
| 680 |
+
k_rot = k_rot.expand(*k_pass.shape[:-1], -1)
|
| 681 |
+
|
| 682 |
+
query_states = torch.cat((q_pass, q_rot), dim=-1)
|
| 683 |
+
key_states = torch.cat((k_pass, k_rot), dim=-1)
|
| 684 |
+
|
| 685 |
+
if past_key_values is not None:
|
| 686 |
+
# sin and cos are specific to RoPE models; cache_position needed for the static cache
|
| 687 |
+
cache_kwargs = {"sin": sin, "cos": cos, "cache_position": cache_position}
|
| 688 |
+
key_states, value_states = past_key_values.update(key_states, value_states, self.layer_idx, cache_kwargs)
|
| 689 |
+
|
| 690 |
+
if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim:
|
| 691 |
+
value_states = F.pad(value_states, [0, self.qk_head_dim - self.v_head_dim])
|
| 692 |
+
|
| 693 |
+
attention_interface: Callable = eager_attention_forward
|
| 694 |
+
|
| 695 |
+
attn_output, attn_weights = attention_interface(
|
| 696 |
+
self,
|
| 697 |
+
query_states,
|
| 698 |
+
key_states,
|
| 699 |
+
value_states,
|
| 700 |
+
attention_mask,
|
| 701 |
+
dropout=0.0 if not self.training else self.attention_dropout,
|
| 702 |
+
scaling=self.scaling,
|
| 703 |
+
**kwargs,
|
| 704 |
+
)
|
| 705 |
+
|
| 706 |
+
if self.config._attn_implementation == "flash_attention_2" and self.qk_head_dim != self.v_head_dim:
|
| 707 |
+
attn_output = attn_output[:, :, :, : self.v_head_dim]
|
| 708 |
+
|
| 709 |
+
if self.g_proj is not None:
|
| 710 |
+
gate = self.g_proj(hidden_states)
|
| 711 |
+
gate = F.sigmoid(gate.float()).type_as(hidden_states)
|
| 712 |
+
if self.gated_attention_proj_granularity_type == "head_wise":
|
| 713 |
+
attn_output = attn_output * gate[:, :, :, None]
|
| 714 |
+
else:
|
| 715 |
+
attn_output = attn_output * gate.view(batch_size, seq_length, self.num_heads, self.v_head_dim)
|
| 716 |
+
|
| 717 |
+
attn_output = attn_output.reshape(batch_size, seq_length, -1).contiguous()
|
| 718 |
+
attn_output = self.dense(attn_output)
|
| 719 |
+
return attn_output, attn_weights, past_key_values
|
| 720 |
+
|
| 721 |
+
|
| 722 |
+
class BailingMoeV3KimiDeltaAttention(nn.Module):
|
| 723 |
+
def __init__(self, config: BailingMoeV3Config, layer_idx: int):
|
| 724 |
+
super().__init__()
|
| 725 |
+
self.config = config
|
| 726 |
+
self.mode = "chunk"
|
| 727 |
+
|
| 728 |
+
self.hidden_size = config.hidden_size
|
| 729 |
+
self.conv_size = config.short_conv_kernel_size
|
| 730 |
+
self.head_dim = config.head_dim
|
| 731 |
+
self.num_heads = config.num_attention_heads
|
| 732 |
+
self.head_k_dim = self.head_dim
|
| 733 |
+
self.num_k_heads = self.num_heads
|
| 734 |
+
self.no_kda_lora = config.no_kda_lora
|
| 735 |
+
self.safe_gate = config.kda_safe_gate
|
| 736 |
+
self.lower_bound = config.kda_lower_bound
|
| 737 |
+
|
| 738 |
+
self.layer_idx = layer_idx
|
| 739 |
+
|
| 740 |
+
assert self.mode in ['chunk', 'fused_recurrent'], f"Not suppoerted mode `{self.mode}`."
|
| 741 |
+
|
| 742 |
+
projection_k_size = self.head_k_dim * self.num_k_heads
|
| 743 |
+
projection_size = self.head_dim * self.num_heads
|
| 744 |
+
|
| 745 |
+
self.q_proj = nn.Linear(self.hidden_size, projection_k_size, bias=False)
|
| 746 |
+
self.k_proj = nn.Linear(self.hidden_size, projection_k_size, bias=False)
|
| 747 |
+
self.v_proj = nn.Linear(self.hidden_size, projection_size, bias=False)
|
| 748 |
+
|
| 749 |
+
self.q_conv1d = ShortConvolution(
|
| 750 |
+
hidden_size=projection_k_size,
|
| 751 |
+
kernel_size=self.conv_size,
|
| 752 |
+
activation='silu',
|
| 753 |
+
)
|
| 754 |
+
self.k_conv1d = ShortConvolution(
|
| 755 |
+
hidden_size=projection_k_size,
|
| 756 |
+
kernel_size=self.conv_size,
|
| 757 |
+
activation='silu',
|
| 758 |
+
)
|
| 759 |
+
self.v_conv1d = ShortConvolution(
|
| 760 |
+
hidden_size=projection_size,
|
| 761 |
+
kernel_size=self.conv_size,
|
| 762 |
+
activation='silu',
|
| 763 |
+
)
|
| 764 |
+
|
| 765 |
+
self.A_log = torch.nn.Parameter(torch.log(torch.empty(self.num_heads, dtype=torch.float32).uniform_(1, 16)))
|
| 766 |
+
|
| 767 |
+
if self.no_kda_lora:
|
| 768 |
+
self.f_proj = nn.Linear(self.hidden_size, projection_size, bias=False)
|
| 769 |
+
else:
|
| 770 |
+
self.f_a_proj = nn.Linear(self.hidden_size, self.head_dim, bias=False)
|
| 771 |
+
self.f_b_proj = nn.Linear(self.head_dim, projection_size, bias=False)
|
| 772 |
+
|
| 773 |
+
self.dt_bias = nn.Parameter(torch.empty(projection_size, dtype=torch.float32))
|
| 774 |
+
|
| 775 |
+
self.b_proj = nn.Linear(self.hidden_size, self.num_heads, bias=False)
|
| 776 |
+
|
| 777 |
+
if self.no_kda_lora:
|
| 778 |
+
self.g_proj = nn.Linear(self.hidden_size, projection_size, bias=False)
|
| 779 |
+
else:
|
| 780 |
+
self.g_a_proj = nn.Linear(self.hidden_size, self.head_dim, bias=False)
|
| 781 |
+
self.g_b_proj = nn.Linear(self.head_dim, projection_size, bias=False)
|
| 782 |
+
|
| 783 |
+
self.o_norm = FusedRMSNormGated(self.head_dim, eps=config.rms_norm_eps, activation='sigmoid')
|
| 784 |
+
self.o_proj = nn.Linear(projection_size, self.hidden_size, bias=False)
|
| 785 |
+
|
| 786 |
+
def forward(
|
| 787 |
+
self,
|
| 788 |
+
hidden_states: torch.Tensor,
|
| 789 |
+
attention_mask: torch.Tensor | None = None,
|
| 790 |
+
past_key_value=None,
|
| 791 |
+
**kwargs: Unpack[dict],
|
| 792 |
+
) -> tuple[torch.Tensor, torch.Tensor | None, Cache | None]:
|
| 793 |
+
attention_mask = None
|
| 794 |
+
if attention_mask is not None:
|
| 795 |
+
if attention_mask.dim() != 2:
|
| 796 |
+
attention_mask = kwargs.get("padding_mask")
|
| 797 |
+
|
| 798 |
+
if attention_mask is not None and attention_mask.dim() != 2:
|
| 799 |
+
raise ValueError(
|
| 800 |
+
"attention_mask must be a 0-1 matrix of shape [batch_size, seq_len] "
|
| 801 |
+
"(0 = padding). 3D masks are not supported here.",
|
| 802 |
+
)
|
| 803 |
+
use_cache = past_key_value is not None
|
| 804 |
+
batch_size, q_len, _ = hidden_states.shape
|
| 805 |
+
mode = 'fused_recurrent' if q_len <= 64 else self.mode
|
| 806 |
+
if self.training:
|
| 807 |
+
assert mode == 'chunk', "Only chunk mode is supported in training."
|
| 808 |
+
|
| 809 |
+
cu_seqlens = kwargs.get('cu_seqlens')
|
| 810 |
+
indices = None
|
| 811 |
+
if attention_mask is not None:
|
| 812 |
+
indices, cu_seqlens, _ = _get_unpad_data(attention_mask[:, -q_len:])
|
| 813 |
+
hidden_states = index_first_axis(rearrange(hidden_states, "b s ... -> (b s) ..."), indices).unsqueeze(0)
|
| 814 |
+
|
| 815 |
+
conv_state_q, conv_state_k, conv_state_v = None, None, None
|
| 816 |
+
recurrent_state = None
|
| 817 |
+
|
| 818 |
+
if past_key_value is not None and isinstance(past_key_value, Cache):
|
| 819 |
+
# ensure the cache list is long enough
|
| 820 |
+
while len(past_key_value.layers) <= self.layer_idx:
|
| 821 |
+
past_key_value.layers.append(DynamicLayer())
|
| 822 |
+
|
| 823 |
+
if past_key_value.layers[self.layer_idx].keys is not None:
|
| 824 |
+
recurrent_state = past_key_value.layers[self.layer_idx].keys
|
| 825 |
+
# ensure recurrent_state is on the same device as hidden_states
|
| 826 |
+
if recurrent_state.device != hidden_states.device:
|
| 827 |
+
recurrent_state = recurrent_state.to(hidden_states.device).contiguous()
|
| 828 |
+
|
| 829 |
+
if past_key_value.layers[self.layer_idx].values is not None:
|
| 830 |
+
conv_state_q, conv_state_k, conv_state_v = past_key_value.layers[self.layer_idx].values
|
| 831 |
+
|
| 832 |
+
q, conv_state_q = self.q_conv1d(
|
| 833 |
+
x=self.q_proj(hidden_states),
|
| 834 |
+
cache=conv_state_q,
|
| 835 |
+
output_final_state=use_cache,
|
| 836 |
+
cu_seqlens=cu_seqlens,
|
| 837 |
+
)
|
| 838 |
+
k, conv_state_k = self.k_conv1d(
|
| 839 |
+
x=self.k_proj(hidden_states),
|
| 840 |
+
cache=conv_state_k,
|
| 841 |
+
output_final_state=use_cache,
|
| 842 |
+
cu_seqlens=cu_seqlens,
|
| 843 |
+
)
|
| 844 |
+
v, conv_state_v = self.v_conv1d(
|
| 845 |
+
x=self.v_proj(hidden_states),
|
| 846 |
+
cache=conv_state_v,
|
| 847 |
+
output_final_state=use_cache,
|
| 848 |
+
cu_seqlens=cu_seqlens,
|
| 849 |
+
)
|
| 850 |
+
|
| 851 |
+
if self.no_kda_lora:
|
| 852 |
+
g = self.f_proj(hidden_states)
|
| 853 |
+
else:
|
| 854 |
+
g = self.f_b_proj(self.f_a_proj(hidden_states))
|
| 855 |
+
|
| 856 |
+
beta = self.b_proj(hidden_states).float().sigmoid()
|
| 857 |
+
|
| 858 |
+
q, k = map(lambda x: rearrange(x, '... (h d) -> ... h d', d=self.head_k_dim), (q, k))
|
| 859 |
+
v = rearrange(v, '... (h d) -> ... h d', d=self.head_dim)
|
| 860 |
+
g = rearrange(g, '... (h d) -> ... h d', d=self.head_dim)
|
| 861 |
+
|
| 862 |
+
if mode == 'chunk':
|
| 863 |
+
o, recurrent_state = chunk_kda(
|
| 864 |
+
q=q,
|
| 865 |
+
k=k,
|
| 866 |
+
v=v,
|
| 867 |
+
g=g,
|
| 868 |
+
beta=beta,
|
| 869 |
+
A_log=self.A_log,
|
| 870 |
+
dt_bias=self.dt_bias,
|
| 871 |
+
initial_state=recurrent_state,
|
| 872 |
+
output_final_state=True,
|
| 873 |
+
use_qk_l2norm_in_kernel=True,
|
| 874 |
+
use_gate_in_kernel=True,
|
| 875 |
+
safe_gate=self.safe_gate,
|
| 876 |
+
lower_bound=self.lower_bound,
|
| 877 |
+
cu_seqlens=cu_seqlens,
|
| 878 |
+
)
|
| 879 |
+
else:
|
| 880 |
+
o, recurrent_state = fused_recurrent_kda(
|
| 881 |
+
q=q,
|
| 882 |
+
k=k,
|
| 883 |
+
v=v,
|
| 884 |
+
g=g,
|
| 885 |
+
beta=beta,
|
| 886 |
+
A_log=self.A_log,
|
| 887 |
+
dt_bias=self.dt_bias,
|
| 888 |
+
initial_state=recurrent_state,
|
| 889 |
+
output_final_state=True,
|
| 890 |
+
use_qk_l2norm_in_kernel=True,
|
| 891 |
+
use_gate_in_kernel=True,
|
| 892 |
+
lower_bound=self.lower_bound,
|
| 893 |
+
cu_seqlens=cu_seqlens,
|
| 894 |
+
)
|
| 895 |
+
|
| 896 |
+
if use_cache and past_key_value is not None and isinstance(past_key_value, Cache):
|
| 897 |
+
target_device = None
|
| 898 |
+
for cache in past_key_value.layers:
|
| 899 |
+
if cache.keys is not None:
|
| 900 |
+
target_device = cache.keys.device
|
| 901 |
+
break
|
| 902 |
+
if target_device is None:
|
| 903 |
+
target_device = recurrent_state.device
|
| 904 |
+
|
| 905 |
+
# move to target device
|
| 906 |
+
if recurrent_state.device != target_device:
|
| 907 |
+
recurrent_state = recurrent_state.to(target_device)
|
| 908 |
+
|
| 909 |
+
past_key_value.layers[self.layer_idx].keys = recurrent_state
|
| 910 |
+
past_key_value.layers[self.layer_idx].values = (conv_state_q, conv_state_k, conv_state_v)
|
| 911 |
+
|
| 912 |
+
if self.no_kda_lora:
|
| 913 |
+
g = self.g_proj(hidden_states)
|
| 914 |
+
else:
|
| 915 |
+
g = self.g_b_proj(self.g_a_proj(hidden_states))
|
| 916 |
+
g = rearrange(g, '... (h d) -> ... h d', d=self.head_dim)
|
| 917 |
+
o = self.o_norm(o, g)
|
| 918 |
+
|
| 919 |
+
o = rearrange(o, 'b t h d -> b t (h d)')
|
| 920 |
+
o = self.o_proj(o)
|
| 921 |
+
if attention_mask is not None:
|
| 922 |
+
o = pad_input(o.squeeze(0), indices, batch_size, q_len)
|
| 923 |
+
|
| 924 |
+
return o, None, past_key_value
|
| 925 |
+
|
| 926 |
+
|
| 927 |
+
class BailingMoeV3MTPLayer(nn.Module):
|
| 928 |
+
def __init__(self, config: BailingMoeV3Config, layer_idx: int):
|
| 929 |
+
super().__init__()
|
| 930 |
+
self.layer_idx = layer_idx
|
| 931 |
+
self.input_layernorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 932 |
+
self.enorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 933 |
+
|
| 934 |
+
self.eh_proj = nn.Linear(config.hidden_size * 2, config.hidden_size, bias=False)
|
| 935 |
+
self.post_attention_layernorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 936 |
+
self.attention = BailingMoeV3MultiLatentAttention(config=config, layer_idx=layer_idx)
|
| 937 |
+
self.mlp = BailingMoeV3SparseMoeBlock(config)
|
| 938 |
+
|
| 939 |
+
self.hnorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 940 |
+
self.final_layernorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 941 |
+
|
| 942 |
+
def forward(
|
| 943 |
+
self,
|
| 944 |
+
input_embeds,
|
| 945 |
+
hidden_states: torch.Tensor,
|
| 946 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 947 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 948 |
+
past_key_value: Optional[Tuple[torch.Tensor]] = None,
|
| 949 |
+
output_attentions: Optional[bool] = False,
|
| 950 |
+
output_router_logits: Optional[bool] = False,
|
| 951 |
+
use_cache: Optional[bool] = False,
|
| 952 |
+
position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC
|
| 953 |
+
**kwargs,
|
| 954 |
+
) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
|
| 955 |
+
input_embeds = self.enorm(input_embeds)
|
| 956 |
+
hidden_states = self.hnorm(hidden_states)
|
| 957 |
+
hidden_states = self.eh_proj(torch.cat([input_embeds, hidden_states], dim=-1))
|
| 958 |
+
residual = hidden_states
|
| 959 |
+
|
| 960 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 961 |
+
|
| 962 |
+
# Self Attention
|
| 963 |
+
hidden_states, self_attn_weights, present_key_value = self.attention(
|
| 964 |
+
hidden_states=hidden_states,
|
| 965 |
+
attention_mask=attention_mask,
|
| 966 |
+
position_ids=position_ids,
|
| 967 |
+
past_key_value=past_key_value,
|
| 968 |
+
output_attentions=output_attentions,
|
| 969 |
+
position_embeddings=position_embeddings,
|
| 970 |
+
use_cache=use_cache,
|
| 971 |
+
)
|
| 972 |
+
hidden_states = residual + hidden_states
|
| 973 |
+
|
| 974 |
+
# Fully Connected
|
| 975 |
+
residual = hidden_states
|
| 976 |
+
hidden_states = self.post_attention_layernorm(hidden_states)
|
| 977 |
+
hidden_states = self.mlp(hidden_states)
|
| 978 |
+
if isinstance(hidden_states, tuple):
|
| 979 |
+
hidden_states, router_logits = hidden_states
|
| 980 |
+
else:
|
| 981 |
+
router_logits = None
|
| 982 |
+
hidden_states = residual + hidden_states.to(residual.device)
|
| 983 |
+
hidden_states = self.final_layernorm(hidden_states)
|
| 984 |
+
|
| 985 |
+
outputs = (hidden_states,)
|
| 986 |
+
|
| 987 |
+
if output_attentions:
|
| 988 |
+
outputs += (self_attn_weights,)
|
| 989 |
+
|
| 990 |
+
if use_cache:
|
| 991 |
+
outputs += (present_key_value,)
|
| 992 |
+
|
| 993 |
+
if output_router_logits:
|
| 994 |
+
outputs += (router_logits,)
|
| 995 |
+
|
| 996 |
+
return outputs
|
| 997 |
+
|
| 998 |
+
|
| 999 |
+
class BailingMoeV3DecoderLayer(nn.Module):
|
| 1000 |
+
def __init__(self, config: BailingMoeV3Config, layer_idx: int):
|
| 1001 |
+
super().__init__()
|
| 1002 |
+
self.hidden_size = config.hidden_size
|
| 1003 |
+
self.layer_idx = layer_idx
|
| 1004 |
+
self.attention_layer_type = (
|
| 1005 |
+
"attention"
|
| 1006 |
+
if (layer_idx + 1) % config.layer_group_size == 0
|
| 1007 |
+
or layer_idx >= config.num_hidden_layers // config.layer_group_size * config.layer_group_size
|
| 1008 |
+
else "linear_attention"
|
| 1009 |
+
)
|
| 1010 |
+
|
| 1011 |
+
if self.attention_layer_type == "attention":
|
| 1012 |
+
self.attention = BailingMoeV3MultiLatentAttention(config=config, layer_idx=layer_idx)
|
| 1013 |
+
else:
|
| 1014 |
+
self.attention = BailingMoeV3KimiDeltaAttention(config=config, layer_idx=layer_idx)
|
| 1015 |
+
|
| 1016 |
+
self.mlp = (
|
| 1017 |
+
BailingMoeV3SparseMoeBlock(config)
|
| 1018 |
+
if (config.num_experts is not None and layer_idx >= config.first_k_dense_replace)
|
| 1019 |
+
else BailingMoeV3MLP(config=config, intermediate_size=config.intermediate_size)
|
| 1020 |
+
)
|
| 1021 |
+
self.input_layernorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 1022 |
+
self.post_attention_layernorm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 1023 |
+
|
| 1024 |
+
def forward(
|
| 1025 |
+
self,
|
| 1026 |
+
hidden_states: torch.Tensor,
|
| 1027 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 1028 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 1029 |
+
past_key_value: Optional[Tuple[torch.Tensor]] = None,
|
| 1030 |
+
cache_position: Optional[torch.LongTensor] = None,
|
| 1031 |
+
output_attentions: Optional[bool] = False,
|
| 1032 |
+
output_router_logits: Optional[bool] = False,
|
| 1033 |
+
use_cache: Optional[bool] = False,
|
| 1034 |
+
position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None, # necessary, but kept here for BC
|
| 1035 |
+
**kwargs,
|
| 1036 |
+
) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
|
| 1037 |
+
"""
|
| 1038 |
+
Args:
|
| 1039 |
+
hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
|
| 1040 |
+
attention_mask (`torch.FloatTensor`, *optional*):
|
| 1041 |
+
attention mask of size `(batch_size, sequence_length)` if flash attention is used or `(batch_size, 1,
|
| 1042 |
+
query_sequence_length, key_sequence_length)` if default attention is used.
|
| 1043 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1044 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 1045 |
+
config.n_positions - 1]`.
|
| 1046 |
+
past_key_value (`Tuple(torch.FloatTensor)`, *optional*):
|
| 1047 |
+
cached past key and value projection states
|
| 1048 |
+
output_attentions (`bool`, *optional*):
|
| 1049 |
+
Whether to return the attentions tensors of all attention layers. See `attentions` under
|
| 1050 |
+
returned tensors for more detail.
|
| 1051 |
+
output_router_logits (`bool`, *optional*):
|
| 1052 |
+
Whether or not to return the logits of all the routers. They are useful for computing the router loss,
|
| 1053 |
+
and should not be returned during inference.
|
| 1054 |
+
use_cache (`bool`, *optional*):
|
| 1055 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding
|
| 1056 |
+
(see `past_key_values`).
|
| 1057 |
+
"""
|
| 1058 |
+
residual = hidden_states
|
| 1059 |
+
|
| 1060 |
+
hidden_states = self.input_layernorm(hidden_states)
|
| 1061 |
+
|
| 1062 |
+
# Self Attention
|
| 1063 |
+
if self.attention_layer_type == "attention":
|
| 1064 |
+
hidden_states, self_attn_weights, present_key_value = self.attention(
|
| 1065 |
+
hidden_states=hidden_states,
|
| 1066 |
+
attention_mask=attention_mask,
|
| 1067 |
+
position_ids=position_ids,
|
| 1068 |
+
past_key_values=past_key_value,
|
| 1069 |
+
use_cache=use_cache,
|
| 1070 |
+
cache_position=cache_position, #
|
| 1071 |
+
position_embeddings=position_embeddings, #
|
| 1072 |
+
**kwargs,
|
| 1073 |
+
)
|
| 1074 |
+
else:
|
| 1075 |
+
batch_size, seq_len = hidden_states.shape[0], hidden_states.shape[1]
|
| 1076 |
+
device = hidden_states.device
|
| 1077 |
+
|
| 1078 |
+
if attention_mask is None:
|
| 1079 |
+
# if attention_mask is None, create a full mask
|
| 1080 |
+
attention_mask = torch.ones((batch_size, seq_len), dtype=torch.int32, device=device)
|
| 1081 |
+
elif attention_mask.dim() == 4 and attention_mask.shape[1] == 1:
|
| 1082 |
+
attention_mask = attention_mask[:, 0, -1, :].to(torch.int32)
|
| 1083 |
+
attention_mask = (attention_mask > -1e4).to(torch.int32)
|
| 1084 |
+
elif attention_mask.dim() == 2:
|
| 1085 |
+
attention_mask = attention_mask.to(torch.int32)
|
| 1086 |
+
else:
|
| 1087 |
+
raise ValueError(f"Unsupported mask dimension: {attention_mask.shape}")
|
| 1088 |
+
|
| 1089 |
+
hidden_states, self_attn_weights, present_key_value = self.attention(
|
| 1090 |
+
hidden_states=hidden_states,
|
| 1091 |
+
attention_mask=attention_mask,
|
| 1092 |
+
past_key_value=past_key_value,
|
| 1093 |
+
position_ids=position_ids,
|
| 1094 |
+
use_cache=use_cache,
|
| 1095 |
+
output_attentions=output_attentions,
|
| 1096 |
+
)
|
| 1097 |
+
|
| 1098 |
+
hidden_states = residual + hidden_states
|
| 1099 |
+
|
| 1100 |
+
# Fully Connected
|
| 1101 |
+
residual = hidden_states
|
| 1102 |
+
hidden_states = self.post_attention_layernorm(hidden_states)
|
| 1103 |
+
hidden_states = self.mlp(hidden_states)
|
| 1104 |
+
if isinstance(hidden_states, tuple):
|
| 1105 |
+
hidden_states, router_logits = hidden_states
|
| 1106 |
+
else:
|
| 1107 |
+
router_logits = None
|
| 1108 |
+
hidden_states = residual + hidden_states.to(residual.device)
|
| 1109 |
+
|
| 1110 |
+
outputs = (hidden_states,)
|
| 1111 |
+
|
| 1112 |
+
if output_attentions:
|
| 1113 |
+
outputs += (self_attn_weights,)
|
| 1114 |
+
|
| 1115 |
+
if use_cache:
|
| 1116 |
+
outputs += (present_key_value,)
|
| 1117 |
+
|
| 1118 |
+
if output_router_logits:
|
| 1119 |
+
outputs += (router_logits,)
|
| 1120 |
+
|
| 1121 |
+
return outputs
|
| 1122 |
+
|
| 1123 |
+
|
| 1124 |
+
BAILINGMOEV3_START_DOCSTRING = r"""
|
| 1125 |
+
This model inherits from [`PreTrainedModel`]. Check the superclass documentation for the generic methods the
|
| 1126 |
+
library implements for all its model (such as downloading or saving, resizing the input embeddings, pruning heads
|
| 1127 |
+
etc.)
|
| 1128 |
+
This model is also a PyTorch [torch.nn.Module](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) subclass.
|
| 1129 |
+
Use it as a regular PyTorch Module and refer to the PyTorch documentation for all matter related to general usage
|
| 1130 |
+
and behavior.
|
| 1131 |
+
Parameters:
|
| 1132 |
+
config ([`BailingMoeV3Config`]):
|
| 1133 |
+
Model configuration class with all the parameters of the model. Initializing with a config file does not
|
| 1134 |
+
load the weights associated with the model, only the configuration. Check out the
|
| 1135 |
+
[`~PreTrainedModel.from_pretrained`] method to load the model weights.
|
| 1136 |
+
"""
|
| 1137 |
+
|
| 1138 |
+
|
| 1139 |
+
@add_start_docstrings(
|
| 1140 |
+
"The bare BailingMoeV3 Model outputting raw hidden-states without any specific head on top.",
|
| 1141 |
+
BAILINGMOEV3_START_DOCSTRING,
|
| 1142 |
+
)
|
| 1143 |
+
class BailingMoeV3PreTrainedModel(PreTrainedModel):
|
| 1144 |
+
config_class = BailingMoeV3Config
|
| 1145 |
+
base_model_prefix = "model"
|
| 1146 |
+
supports_gradient_checkpointing = True
|
| 1147 |
+
_no_split_modules = ["BailingMoeV3DecoderLayer"]
|
| 1148 |
+
_skip_keys_device_placement = "past_key_values"
|
| 1149 |
+
_supports_flash_attn_2 = True
|
| 1150 |
+
_supports_sdpa = True
|
| 1151 |
+
_supports_cache_class = True
|
| 1152 |
+
|
| 1153 |
+
def _init_weights(self, module):
|
| 1154 |
+
std = self.config.initializer_range
|
| 1155 |
+
if isinstance(module, nn.Linear):
|
| 1156 |
+
module.weight.data.normal_(mean=0.0, std=std)
|
| 1157 |
+
if module.bias is not None:
|
| 1158 |
+
module.bias.data.zero_()
|
| 1159 |
+
elif isinstance(module, nn.Embedding):
|
| 1160 |
+
module.weight.data.normal_(mean=0.0, std=std)
|
| 1161 |
+
if module.padding_idx is not None:
|
| 1162 |
+
module.weight.data[module.padding_idx].zero_()
|
| 1163 |
+
|
| 1164 |
+
|
| 1165 |
+
BAILINGMOEV3_INPUTS_DOCSTRING = r"""
|
| 1166 |
+
Args:
|
| 1167 |
+
input_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`):
|
| 1168 |
+
Indices of input sequence tokens in the vocabulary. Padding will be ignored by default should you provide
|
| 1169 |
+
it.
|
| 1170 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1171 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1172 |
+
[What are input IDs?](../glossary#input-ids)
|
| 1173 |
+
attention_mask (`torch.Tensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1174 |
+
Mask to avoid performing attention on padding token indices. Mask values selected in `[0, 1]`:
|
| 1175 |
+
- 1 for tokens that are **not masked**,
|
| 1176 |
+
- 0 for tokens that are **masked**.
|
| 1177 |
+
[What are attention masks?](../glossary#attention-mask)
|
| 1178 |
+
Indices can be obtained using [`AutoTokenizer`]. See [`PreTrainedTokenizer.encode`] and
|
| 1179 |
+
[`PreTrainedTokenizer.__call__`] for details.
|
| 1180 |
+
If `past_key_values` is used, optionally only the last `input_ids` have to be input (see
|
| 1181 |
+
`past_key_values`).
|
| 1182 |
+
If you want to change padding behavior, you should read [`modeling_opt._prepare_decoder_attention_mask`]
|
| 1183 |
+
and modify to your needs. See diagram 1 in [the paper](https://arxiv.org/abs/1910.13461) for more
|
| 1184 |
+
information on the default strategy.
|
| 1185 |
+
- 1 indicates the head is **not masked**,
|
| 1186 |
+
- 0 indicates the head is **masked**.
|
| 1187 |
+
position_ids (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1188 |
+
Indices of positions of each input sequence tokens in the position embeddings. Selected in the range `[0,
|
| 1189 |
+
config.n_positions - 1]`.
|
| 1190 |
+
[What are position IDs?](../glossary#position-ids)
|
| 1191 |
+
past_key_values (`Cache` or `tuple(tuple(torch.FloatTensor))`, *optional*):
|
| 1192 |
+
Pre-computed hidden-states (key and values in the self-attention blocks and in the cross-attention
|
| 1193 |
+
blocks) that can be used to speed up sequential decoding. This typically consists in the `past_key_values`
|
| 1194 |
+
returned by the model at a previous stage of decoding, when `use_cache=True` or `config.use_cache=True`.
|
| 1195 |
+
Two formats are allowed:
|
| 1196 |
+
- a [`~cache_utils.Cache`] instance;
|
| 1197 |
+
- Tuple of `tuple(torch.FloatTensor)` of length `config.n_layers`, with each tuple having 2 tensors of
|
| 1198 |
+
shape `(batch_size, num_heads, sequence_length, embed_size_per_head)`). This is also known as the legacy
|
| 1199 |
+
cache format.
|
| 1200 |
+
The model will output the same cache format that is fed as input. If no `past_key_values` are passed, the
|
| 1201 |
+
legacy cache format will be returned.
|
| 1202 |
+
If `past_key_values` are used, the user can optionally input only the last `input_ids` (those that don't
|
| 1203 |
+
have their past key value states given to this model) of shape `(batch_size, 1)` instead of all `input_ids`
|
| 1204 |
+
of shape `(batch_size, sequence_length)`.
|
| 1205 |
+
inputs_embeds (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`, *optional*):
|
| 1206 |
+
Optionally, instead of passing `input_ids` you can choose to directly pass an embedded representation. This
|
| 1207 |
+
is useful if you want more control over how to convert `input_ids` indices into associated vectors than the
|
| 1208 |
+
model's internal embedding lookup matrix.
|
| 1209 |
+
use_cache (`bool`, *optional*):
|
| 1210 |
+
If set to `True`, `past_key_values` key value states are returned and can be used to speed up decoding (see
|
| 1211 |
+
`past_key_values`).
|
| 1212 |
+
output_attentions (`bool`, *optional*):
|
| 1213 |
+
Whether or not to return the attentions tensors of all attention layers. See `attentions` under returned
|
| 1214 |
+
tensors for more detail.
|
| 1215 |
+
output_hidden_states (`bool`, *optional*):
|
| 1216 |
+
Whether or not to return the hidden states of all layers. See `hidden_states` under returned tensors for
|
| 1217 |
+
more detail.
|
| 1218 |
+
return_dict (`bool`, *optional*):
|
| 1219 |
+
Whether or not to return a [`~utils.ModelOutput`] instead of a plain tuple.
|
| 1220 |
+
"""
|
| 1221 |
+
|
| 1222 |
+
|
| 1223 |
+
@add_start_docstrings(
|
| 1224 |
+
"The bare BailingMoeV3 Model outputting raw hidden-states without any specific head on top.",
|
| 1225 |
+
BAILINGMOEV3_START_DOCSTRING,
|
| 1226 |
+
)
|
| 1227 |
+
class BailingMoeV3Model(BailingMoeV3PreTrainedModel):
|
| 1228 |
+
"""
|
| 1229 |
+
Transformer decoder consisting of *config.num_hidden_layers* layers. Each layer is a [`BailingMoeV3DecoderLayer`]
|
| 1230 |
+
Args:
|
| 1231 |
+
config: BailingMoeV3Config
|
| 1232 |
+
"""
|
| 1233 |
+
|
| 1234 |
+
def __init__(self, config: BailingMoeV3Config):
|
| 1235 |
+
super().__init__(config)
|
| 1236 |
+
self.padding_idx = config.pad_token_id
|
| 1237 |
+
self.vocab_size = config.vocab_size
|
| 1238 |
+
self.num_nextn_predict_layers = config.num_nextn_predict_layers
|
| 1239 |
+
|
| 1240 |
+
self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
|
| 1241 |
+
self.layers = []
|
| 1242 |
+
for layer_idx in range(config.num_hidden_layers + config.num_nextn_predict_layers):
|
| 1243 |
+
layer_cls = BailingMoeV3DecoderLayer if layer_idx < config.num_hidden_layers else BailingMoeV3MTPLayer
|
| 1244 |
+
self.layers.append(layer_cls(config, layer_idx))
|
| 1245 |
+
|
| 1246 |
+
self.layers = nn.ModuleList(self.layers)
|
| 1247 |
+
|
| 1248 |
+
self._use_sdpa = config._attn_implementation == "sdpa"
|
| 1249 |
+
self._use_flash_attention_2 = config._attn_implementation == "flash_attention_2"
|
| 1250 |
+
self.norm = BailingMoeV3RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
| 1251 |
+
self.rotary_emb = BailingMoeV3RotaryEmbedding(config=config)
|
| 1252 |
+
self.gradient_checkpointing = False
|
| 1253 |
+
# Initialize weights and apply final processing
|
| 1254 |
+
self.post_init()
|
| 1255 |
+
|
| 1256 |
+
def get_input_embeddings(self):
|
| 1257 |
+
return self.word_embeddings
|
| 1258 |
+
|
| 1259 |
+
def set_input_embeddings(self, value):
|
| 1260 |
+
self.word_embeddings = value
|
| 1261 |
+
|
| 1262 |
+
@add_start_docstrings_to_model_forward(BAILINGMOEV3_INPUTS_DOCSTRING)
|
| 1263 |
+
def forward(
|
| 1264 |
+
self,
|
| 1265 |
+
input_ids: torch.LongTensor = None,
|
| 1266 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 1267 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 1268 |
+
past_key_values: Optional[List[torch.FloatTensor]] = None,
|
| 1269 |
+
inputs_embeds: Optional[torch.FloatTensor] = None,
|
| 1270 |
+
cache_position: Optional[torch.LongTensor] = None,
|
| 1271 |
+
use_cache: Optional[bool] = None,
|
| 1272 |
+
output_attentions: Optional[bool] = None,
|
| 1273 |
+
output_hidden_states: Optional[bool] = None,
|
| 1274 |
+
output_router_logits: Optional[bool] = None,
|
| 1275 |
+
return_dict: Optional[bool] = None,
|
| 1276 |
+
**kwargs,
|
| 1277 |
+
) -> Union[Tuple, MoeV3ModelOutputWithPast]:
|
| 1278 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 1279 |
+
output_hidden_states = (
|
| 1280 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 1281 |
+
)
|
| 1282 |
+
output_router_logits = (
|
| 1283 |
+
output_router_logits if output_router_logits is not None else self.config.output_router_logits
|
| 1284 |
+
)
|
| 1285 |
+
use_cache = use_cache if use_cache is not None else self.config.use_cache
|
| 1286 |
+
|
| 1287 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 1288 |
+
|
| 1289 |
+
# retrieve input_ids and inputs_embeds
|
| 1290 |
+
if input_ids is not None and inputs_embeds is not None:
|
| 1291 |
+
raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
|
| 1292 |
+
elif input_ids is not None:
|
| 1293 |
+
batch_size, seq_length = input_ids.shape[:2]
|
| 1294 |
+
elif inputs_embeds is not None:
|
| 1295 |
+
batch_size, seq_length = inputs_embeds.shape[:2]
|
| 1296 |
+
else:
|
| 1297 |
+
raise ValueError("You have to specify either input_ids or inputs_embeds")
|
| 1298 |
+
|
| 1299 |
+
if self.gradient_checkpointing and self.training:
|
| 1300 |
+
if use_cache:
|
| 1301 |
+
logger.warning_once(
|
| 1302 |
+
"`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`transformers."
|
| 1303 |
+
)
|
| 1304 |
+
use_cache = False
|
| 1305 |
+
|
| 1306 |
+
if use_cache and past_key_values is None:
|
| 1307 |
+
past_key_values = DynamicCache()
|
| 1308 |
+
|
| 1309 |
+
if inputs_embeds is None:
|
| 1310 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 1311 |
+
|
| 1312 |
+
if cache_position is None:
|
| 1313 |
+
past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
|
| 1314 |
+
cache_position: torch.Tensor = torch.arange(
|
| 1315 |
+
past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device
|
| 1316 |
+
)
|
| 1317 |
+
|
| 1318 |
+
if position_ids is None:
|
| 1319 |
+
position_ids = cache_position.unsqueeze(0)
|
| 1320 |
+
|
| 1321 |
+
softmax_attention_layer_id = self.config.layer_group_size - 1
|
| 1322 |
+
past_seen_tokens = (
|
| 1323 |
+
past_key_values.get_seq_length(layer_idx=softmax_attention_layer_id) if past_key_values is not None else 0
|
| 1324 |
+
)
|
| 1325 |
+
|
| 1326 |
+
if position_ids is None:
|
| 1327 |
+
position_ids = torch.arange(
|
| 1328 |
+
past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device
|
| 1329 |
+
)
|
| 1330 |
+
position_ids = position_ids.unsqueeze(0)
|
| 1331 |
+
|
| 1332 |
+
if self._use_flash_attention_2:
|
| 1333 |
+
# 2d mask is passed through the layers
|
| 1334 |
+
attention_mask = attention_mask if (attention_mask is not None and 0 in attention_mask) else None
|
| 1335 |
+
elif self._use_sdpa and not output_attentions:
|
| 1336 |
+
# output_attentions=True can not be supported when using SDPA, and we fall back on
|
| 1337 |
+
# the manual implementation that requires a 4D causal mask in all cases.
|
| 1338 |
+
attention_mask = _prepare_4d_causal_attention_mask_for_sdpa(
|
| 1339 |
+
attention_mask,
|
| 1340 |
+
(batch_size, seq_length),
|
| 1341 |
+
inputs_embeds,
|
| 1342 |
+
past_seen_tokens,
|
| 1343 |
+
)
|
| 1344 |
+
else:
|
| 1345 |
+
# 4d mask is passed through the layers
|
| 1346 |
+
attention_mask = _prepare_4d_causal_attention_mask(
|
| 1347 |
+
attention_mask, (batch_size, seq_length), inputs_embeds, past_seen_tokens
|
| 1348 |
+
)
|
| 1349 |
+
|
| 1350 |
+
# embed positions
|
| 1351 |
+
hidden_states = inputs_embeds
|
| 1352 |
+
|
| 1353 |
+
# create position embeddings to be shared across the decoder layers
|
| 1354 |
+
position_embeddings = self.rotary_emb(hidden_states, position_ids)
|
| 1355 |
+
|
| 1356 |
+
# decoder layers
|
| 1357 |
+
all_hidden_states = () if output_hidden_states else None
|
| 1358 |
+
all_self_attns = () if output_attentions else None
|
| 1359 |
+
all_router_logits = () if output_router_logits else None
|
| 1360 |
+
next_decoder_cache = None
|
| 1361 |
+
layers = self.layers[: -self.num_nextn_predict_layers] if self.num_nextn_predict_layers > 0 else self.layers
|
| 1362 |
+
mtp_layers = self.layers[-self.num_nextn_predict_layers :] if self.num_nextn_predict_layers > 0 else None
|
| 1363 |
+
|
| 1364 |
+
# tptest miss causal_mask = create_causal_mask(
|
| 1365 |
+
|
| 1366 |
+
for decoder_layer in layers:
|
| 1367 |
+
if output_hidden_states:
|
| 1368 |
+
all_hidden_states += (hidden_states,)
|
| 1369 |
+
|
| 1370 |
+
if self.gradient_checkpointing and self.training:
|
| 1371 |
+
layer_outputs = self._gradient_checkpointing_func(
|
| 1372 |
+
decoder_layer.__call__,
|
| 1373 |
+
hidden_states,
|
| 1374 |
+
attention_mask,
|
| 1375 |
+
position_ids,
|
| 1376 |
+
past_key_values,
|
| 1377 |
+
cache_position,
|
| 1378 |
+
output_attentions,
|
| 1379 |
+
output_router_logits,
|
| 1380 |
+
use_cache,
|
| 1381 |
+
position_embeddings,
|
| 1382 |
+
)
|
| 1383 |
+
else:
|
| 1384 |
+
layer_outputs = decoder_layer(
|
| 1385 |
+
hidden_states,
|
| 1386 |
+
attention_mask=attention_mask,
|
| 1387 |
+
position_ids=position_ids,
|
| 1388 |
+
past_key_value=past_key_values,
|
| 1389 |
+
cache_position=cache_position,
|
| 1390 |
+
output_attentions=output_attentions,
|
| 1391 |
+
output_router_logits=output_router_logits,
|
| 1392 |
+
use_cache=use_cache,
|
| 1393 |
+
position_embeddings=position_embeddings,
|
| 1394 |
+
)
|
| 1395 |
+
hidden_states = layer_outputs[0]
|
| 1396 |
+
|
| 1397 |
+
if use_cache:
|
| 1398 |
+
next_decoder_cache = layer_outputs[2 if output_attentions else 1]
|
| 1399 |
+
|
| 1400 |
+
if output_attentions:
|
| 1401 |
+
all_self_attns += (layer_outputs[1],)
|
| 1402 |
+
|
| 1403 |
+
if output_router_logits and layer_outputs[-1] is not None:
|
| 1404 |
+
all_router_logits += (layer_outputs[-1],)
|
| 1405 |
+
|
| 1406 |
+
hidden_states = self.norm(hidden_states)
|
| 1407 |
+
main_hidden_states = hidden_states
|
| 1408 |
+
|
| 1409 |
+
# add hidden states from the last decoder layer
|
| 1410 |
+
if output_hidden_states:
|
| 1411 |
+
all_hidden_states += (main_hidden_states,)
|
| 1412 |
+
|
| 1413 |
+
mtp_hidden_states = None
|
| 1414 |
+
|
| 1415 |
+
if mtp_layers:
|
| 1416 |
+
for decoder_layer in mtp_layers:
|
| 1417 |
+
input_ids, _ = roll_tensor(input_ids, shifts=-1, dims=-1)
|
| 1418 |
+
inputs_embeds = self.word_embeddings(input_ids)
|
| 1419 |
+
|
| 1420 |
+
if self.gradient_checkpointing and self.training:
|
| 1421 |
+
layer_outputs = self._gradient_checkpointing_func(
|
| 1422 |
+
decoder_layer.__call__,
|
| 1423 |
+
inputs_embeds,
|
| 1424 |
+
hidden_states,
|
| 1425 |
+
attention_mask,
|
| 1426 |
+
position_ids,
|
| 1427 |
+
past_key_values,
|
| 1428 |
+
output_attentions,
|
| 1429 |
+
output_router_logits,
|
| 1430 |
+
use_cache,
|
| 1431 |
+
position_embeddings,
|
| 1432 |
+
)
|
| 1433 |
+
else:
|
| 1434 |
+
layer_outputs = decoder_layer(
|
| 1435 |
+
inputs_embeds,
|
| 1436 |
+
hidden_states,
|
| 1437 |
+
attention_mask=attention_mask,
|
| 1438 |
+
position_ids=position_ids,
|
| 1439 |
+
past_key_value=past_key_values,
|
| 1440 |
+
output_attentions=output_attentions,
|
| 1441 |
+
output_router_logits=output_router_logits,
|
| 1442 |
+
use_cache=use_cache,
|
| 1443 |
+
position_embeddings=position_embeddings,
|
| 1444 |
+
)
|
| 1445 |
+
if mtp_hidden_states is None:
|
| 1446 |
+
mtp_hidden_states = []
|
| 1447 |
+
hidden_states = layer_outputs[0]
|
| 1448 |
+
mtp_hidden_states.append(hidden_states)
|
| 1449 |
+
|
| 1450 |
+
if output_hidden_states:
|
| 1451 |
+
all_hidden_states += (hidden_states,)
|
| 1452 |
+
|
| 1453 |
+
if use_cache:
|
| 1454 |
+
next_decoder_cache = layer_outputs[2 if output_attentions else 1]
|
| 1455 |
+
|
| 1456 |
+
if output_attentions:
|
| 1457 |
+
all_self_attns += (layer_outputs[1],)
|
| 1458 |
+
|
| 1459 |
+
if output_router_logits and layer_outputs[-1] is not None:
|
| 1460 |
+
all_router_logits += (layer_outputs[-1],)
|
| 1461 |
+
|
| 1462 |
+
next_cache = None
|
| 1463 |
+
if use_cache:
|
| 1464 |
+
next_cache = next_decoder_cache
|
| 1465 |
+
if not return_dict:
|
| 1466 |
+
return tuple(
|
| 1467 |
+
v
|
| 1468 |
+
for v in [main_hidden_states, next_cache, all_hidden_states, all_self_attns, all_router_logits]
|
| 1469 |
+
if v is not None
|
| 1470 |
+
)
|
| 1471 |
+
return MoeV3ModelOutputWithPast(
|
| 1472 |
+
last_hidden_state=main_hidden_states,
|
| 1473 |
+
past_key_values=next_cache,
|
| 1474 |
+
hidden_states=all_hidden_states,
|
| 1475 |
+
mtp_hidden_states=mtp_hidden_states,
|
| 1476 |
+
attentions=all_self_attns,
|
| 1477 |
+
router_logits=all_router_logits,
|
| 1478 |
+
)
|
| 1479 |
+
|
| 1480 |
+
|
| 1481 |
+
class BailingMoeV3ForCausalLM(BailingMoeV3PreTrainedModel, GenerationMixin):
|
| 1482 |
+
_tied_weights_keys = ["lm_head.weight"]
|
| 1483 |
+
|
| 1484 |
+
def __init__(self, config: BailingMoeV3Config):
|
| 1485 |
+
super().__init__(config)
|
| 1486 |
+
self.model = BailingMoeV3Model(config)
|
| 1487 |
+
self.vocab_size = config.vocab_size
|
| 1488 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 1489 |
+
self.num_nextn_predict_layers = config.num_nextn_predict_layers
|
| 1490 |
+
self.mtp_loss_scaling_factor = config.mtp_loss_scaling_factor
|
| 1491 |
+
|
| 1492 |
+
# Initialize weights and apply final processing
|
| 1493 |
+
self.post_init()
|
| 1494 |
+
|
| 1495 |
+
def get_input_embeddings(self):
|
| 1496 |
+
return self.model.word_embeddings
|
| 1497 |
+
|
| 1498 |
+
def set_input_embeddings(self, value):
|
| 1499 |
+
self.model.word_embeddings = value
|
| 1500 |
+
|
| 1501 |
+
def get_output_embeddings(self):
|
| 1502 |
+
return self.lm_head
|
| 1503 |
+
|
| 1504 |
+
def set_output_embeddings(self, new_embeddings):
|
| 1505 |
+
self.lm_head = new_embeddings
|
| 1506 |
+
|
| 1507 |
+
def set_decoder(self, decoder):
|
| 1508 |
+
self.model = decoder
|
| 1509 |
+
|
| 1510 |
+
def get_decoder(self):
|
| 1511 |
+
return self.model
|
| 1512 |
+
|
| 1513 |
+
@add_start_docstrings_to_model_forward(BAILINGMOEV3_INPUTS_DOCSTRING)
|
| 1514 |
+
@replace_return_docstrings(output_type=MoEV3CausalLMOutputWithPast, config_class=_CONFIG_FOR_DOC)
|
| 1515 |
+
def forward(
|
| 1516 |
+
self,
|
| 1517 |
+
input_ids: torch.LongTensor = None,
|
| 1518 |
+
attention_mask: Optional[torch.Tensor] = None,
|
| 1519 |
+
position_ids: Optional[torch.LongTensor] = None,
|
| 1520 |
+
past_key_values: Optional[List[torch.FloatTensor]] = None,
|
| 1521 |
+
inputs_embeds: Optional[torch.FloatTensor] = None,
|
| 1522 |
+
labels: Optional[torch.LongTensor] = None,
|
| 1523 |
+
use_cache: Optional[bool] = None,
|
| 1524 |
+
output_attentions: Optional[bool] = None,
|
| 1525 |
+
output_hidden_states: Optional[bool] = None,
|
| 1526 |
+
output_router_logits: Optional[bool] = None,
|
| 1527 |
+
return_dict: Optional[bool] = None,
|
| 1528 |
+
**kwargs,
|
| 1529 |
+
) -> Union[Tuple, MoEV3CausalLMOutputWithPast]:
|
| 1530 |
+
r"""
|
| 1531 |
+
Args:
|
| 1532 |
+
labels (`torch.LongTensor` of shape `(batch_size, sequence_length)`, *optional*):
|
| 1533 |
+
Labels for computing the masked language modeling loss. Indices should either be in `[0, ...,
|
| 1534 |
+
config.vocab_size]` or -100 (see `input_ids` docstring). Tokens with indices set to `-100` are ignored
|
| 1535 |
+
(masked), the loss is only computed for the tokens with labels in `[0, ..., config.vocab_size]`.
|
| 1536 |
+
Returns:
|
| 1537 |
+
Example:
|
| 1538 |
+
```python
|
| 1539 |
+
>>> from transformers import AutoTokenizer
|
| 1540 |
+
>>> model = BailingMoeV3ForCausalLM.from_pretrained(PATH_TO_CONVERTED_WEIGHTS)
|
| 1541 |
+
>>> tokenizer = AutoTokenizer.from_pretrained(PATH_TO_CONVERTED_TOKENIZER)
|
| 1542 |
+
>>> prompt = "Hey, are you conscious? Can you talk to me?"
|
| 1543 |
+
>>> inputs = tokenizer(prompt, return_tensors="pt")
|
| 1544 |
+
>>> # Generate
|
| 1545 |
+
>>> generate_ids = model.generate(inputs.input_ids, max_length=30)
|
| 1546 |
+
>>> tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
|
| 1547 |
+
"Hey, are you conscious? Can you talk to me?\nI'm not conscious, but I can talk to you."
|
| 1548 |
+
```"""
|
| 1549 |
+
output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
|
| 1550 |
+
output_hidden_states = (
|
| 1551 |
+
output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
|
| 1552 |
+
)
|
| 1553 |
+
output_router_logits = (
|
| 1554 |
+
output_router_logits if output_router_logits is not None else self.config.output_router_logits
|
| 1555 |
+
)
|
| 1556 |
+
return_dict = return_dict if return_dict is not None else self.config.use_return_dict
|
| 1557 |
+
# decoder outputs consists of (dec_features, layer_state, dec_hidden, dec_attn)
|
| 1558 |
+
outputs = self.model(
|
| 1559 |
+
input_ids=input_ids,
|
| 1560 |
+
attention_mask=attention_mask,
|
| 1561 |
+
position_ids=position_ids,
|
| 1562 |
+
past_key_values=past_key_values,
|
| 1563 |
+
inputs_embeds=inputs_embeds,
|
| 1564 |
+
use_cache=use_cache,
|
| 1565 |
+
output_attentions=output_attentions,
|
| 1566 |
+
output_hidden_states=output_hidden_states,
|
| 1567 |
+
output_router_logits=output_router_logits,
|
| 1568 |
+
return_dict=return_dict,
|
| 1569 |
+
**kwargs,
|
| 1570 |
+
)
|
| 1571 |
+
|
| 1572 |
+
loss = None
|
| 1573 |
+
all_mtp_loss = None
|
| 1574 |
+
aux_loss = None
|
| 1575 |
+
hidden_states = outputs[0]
|
| 1576 |
+
logits = self.lm_head(hidden_states)
|
| 1577 |
+
logits = logits.float()
|
| 1578 |
+
|
| 1579 |
+
if labels is not None:
|
| 1580 |
+
loss = self.loss_function(logits, labels, self.config.vocab_size, **kwargs)
|
| 1581 |
+
|
| 1582 |
+
all_mtp_logits = None
|
| 1583 |
+
if self.num_nextn_predict_layers > 0:
|
| 1584 |
+
mtp_hidden_states = outputs.mtp_hidden_states
|
| 1585 |
+
shift_labels_mtp = None
|
| 1586 |
+
for i in range(self.num_nextn_predict_layers):
|
| 1587 |
+
mtp_hidden_states = mtp_hidden_states[i]
|
| 1588 |
+
mtp_logits = self.lm_head(mtp_hidden_states).float()
|
| 1589 |
+
if all_mtp_logits is None:
|
| 1590 |
+
all_mtp_logits = []
|
| 1591 |
+
all_mtp_logits.append(mtp_logits)
|
| 1592 |
+
if labels is not None:
|
| 1593 |
+
if shift_labels_mtp is None:
|
| 1594 |
+
shift_labels_mtp = labels.clone()
|
| 1595 |
+
shift_labels_mtp, _ = roll_tensor(shift_labels_mtp, shifts=-1, dims=-1, fill_value=-100)
|
| 1596 |
+
mtp_logits_ = mtp_logits.view(-1, self.config.vocab_size)
|
| 1597 |
+
mtp_loss = self.loss_function(
|
| 1598 |
+
mtp_logits_, shift_labels_mtp.to(mtp_logits_.device).view(-1), self.config.vocab_size, **kwargs
|
| 1599 |
+
)
|
| 1600 |
+
if loss is not None:
|
| 1601 |
+
loss += self.mtp_loss_scaling_factor * mtp_loss
|
| 1602 |
+
else:
|
| 1603 |
+
loss = self.mtp_loss_scaling_factor * mtp_loss
|
| 1604 |
+
|
| 1605 |
+
if all_mtp_loss is None:
|
| 1606 |
+
all_mtp_loss = []
|
| 1607 |
+
all_mtp_loss.append(mtp_loss)
|
| 1608 |
+
|
| 1609 |
+
if not return_dict:
|
| 1610 |
+
output = (logits,) + outputs[1:]
|
| 1611 |
+
if output_router_logits:
|
| 1612 |
+
output = (aux_loss,) + output
|
| 1613 |
+
return (loss,) + output if loss is not None else output
|
| 1614 |
+
|
| 1615 |
+
return MoEV3CausalLMOutputWithPast(
|
| 1616 |
+
loss=loss,
|
| 1617 |
+
mtp_loss=all_mtp_loss,
|
| 1618 |
+
aux_loss=aux_loss,
|
| 1619 |
+
logits=logits,
|
| 1620 |
+
mtp_logits=all_mtp_logits,
|
| 1621 |
+
past_key_values=outputs.past_key_values,
|
| 1622 |
+
hidden_states=outputs.hidden_states,
|
| 1623 |
+
attentions=outputs.attentions,
|
| 1624 |
+
router_logits=outputs.router_logits,
|
| 1625 |
+
)
|
special_tokens_map.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"bos_token": {
|
| 3 |
+
"content": "<|startoftext|>",
|
| 4 |
+
"lstrip": false,
|
| 5 |
+
"normalized": false,
|
| 6 |
+
"rstrip": false,
|
| 7 |
+
"single_word": false
|
| 8 |
+
},
|
| 9 |
+
"cls_token": {
|
| 10 |
+
"content": "[CLS]",
|
| 11 |
+
"lstrip": false,
|
| 12 |
+
"normalized": false,
|
| 13 |
+
"rstrip": false,
|
| 14 |
+
"single_word": false
|
| 15 |
+
},
|
| 16 |
+
"eos_token": {
|
| 17 |
+
"content": "<|role_end|>",
|
| 18 |
+
"lstrip": false,
|
| 19 |
+
"normalized": false,
|
| 20 |
+
"rstrip": false,
|
| 21 |
+
"single_word": false
|
| 22 |
+
},
|
| 23 |
+
"pad_token": {
|
| 24 |
+
"content": "<|endoftext|>",
|
| 25 |
+
"lstrip": false,
|
| 26 |
+
"normalized": false,
|
| 27 |
+
"rstrip": false,
|
| 28 |
+
"single_word": false
|
| 29 |
+
}
|
| 30 |
+
}
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:40fb9d7d7795b8bd305aeff39ce9963f3f450915b9553f2938e009be9a1fed60
|
| 3 |
+
size 12205732
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,2113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_bos_token": false,
|
| 3 |
+
"add_eos_token": false,
|
| 4 |
+
"added_tokens_decoder": {
|
| 5 |
+
"156891": {
|
| 6 |
+
"content": "<|startoftext|>",
|
| 7 |
+
"lstrip": false,
|
| 8 |
+
"normalized": false,
|
| 9 |
+
"rstrip": false,
|
| 10 |
+
"single_word": false,
|
| 11 |
+
"special": true
|
| 12 |
+
},
|
| 13 |
+
"156892": {
|
| 14 |
+
"content": "<|endoftext|>",
|
| 15 |
+
"lstrip": false,
|
| 16 |
+
"normalized": false,
|
| 17 |
+
"rstrip": false,
|
| 18 |
+
"single_word": false,
|
| 19 |
+
"special": true
|
| 20 |
+
},
|
| 21 |
+
"156893": {
|
| 22 |
+
"content": "[CLS]",
|
| 23 |
+
"lstrip": false,
|
| 24 |
+
"normalized": false,
|
| 25 |
+
"rstrip": false,
|
| 26 |
+
"single_word": false,
|
| 27 |
+
"special": true
|
| 28 |
+
},
|
| 29 |
+
"156894": {
|
| 30 |
+
"content": "[gMASK]",
|
| 31 |
+
"lstrip": false,
|
| 32 |
+
"normalized": false,
|
| 33 |
+
"rstrip": false,
|
| 34 |
+
"single_word": false,
|
| 35 |
+
"special": true
|
| 36 |
+
},
|
| 37 |
+
"156895": {
|
| 38 |
+
"content": "<|role_end|>",
|
| 39 |
+
"lstrip": false,
|
| 40 |
+
"normalized": false,
|
| 41 |
+
"rstrip": false,
|
| 42 |
+
"single_word": false,
|
| 43 |
+
"special": true
|
| 44 |
+
},
|
| 45 |
+
"156896": {
|
| 46 |
+
"content": "<tool_call>",
|
| 47 |
+
"lstrip": false,
|
| 48 |
+
"normalized": false,
|
| 49 |
+
"rstrip": false,
|
| 50 |
+
"single_word": false,
|
| 51 |
+
"special": false
|
| 52 |
+
},
|
| 53 |
+
"156897": {
|
| 54 |
+
"content": "</tool_call>",
|
| 55 |
+
"lstrip": false,
|
| 56 |
+
"normalized": false,
|
| 57 |
+
"rstrip": false,
|
| 58 |
+
"single_word": false,
|
| 59 |
+
"special": false
|
| 60 |
+
},
|
| 61 |
+
"156898": {
|
| 62 |
+
"content": "<tool_response>",
|
| 63 |
+
"lstrip": false,
|
| 64 |
+
"normalized": false,
|
| 65 |
+
"rstrip": false,
|
| 66 |
+
"single_word": false,
|
| 67 |
+
"special": false
|
| 68 |
+
},
|
| 69 |
+
"156899": {
|
| 70 |
+
"content": "</tool_response>",
|
| 71 |
+
"lstrip": false,
|
| 72 |
+
"normalized": false,
|
| 73 |
+
"rstrip": false,
|
| 74 |
+
"single_word": false,
|
| 75 |
+
"special": false
|
| 76 |
+
},
|
| 77 |
+
"156900": {
|
| 78 |
+
"content": "<|fim_start|>",
|
| 79 |
+
"lstrip": false,
|
| 80 |
+
"normalized": false,
|
| 81 |
+
"rstrip": false,
|
| 82 |
+
"single_word": false,
|
| 83 |
+
"special": true
|
| 84 |
+
},
|
| 85 |
+
"156901": {
|
| 86 |
+
"content": "<|fim_hole|>",
|
| 87 |
+
"lstrip": false,
|
| 88 |
+
"normalized": false,
|
| 89 |
+
"rstrip": false,
|
| 90 |
+
"single_word": false,
|
| 91 |
+
"special": true
|
| 92 |
+
},
|
| 93 |
+
"156902": {
|
| 94 |
+
"content": "<|fim_end|>",
|
| 95 |
+
"lstrip": false,
|
| 96 |
+
"normalized": false,
|
| 97 |
+
"rstrip": false,
|
| 98 |
+
"single_word": false,
|
| 99 |
+
"special": true
|
| 100 |
+
},
|
| 101 |
+
"156903": {
|
| 102 |
+
"content": "<think>",
|
| 103 |
+
"lstrip": false,
|
| 104 |
+
"normalized": false,
|
| 105 |
+
"rstrip": false,
|
| 106 |
+
"single_word": false,
|
| 107 |
+
"special": false
|
| 108 |
+
},
|
| 109 |
+
"156904": {
|
| 110 |
+
"content": "</think>",
|
| 111 |
+
"lstrip": false,
|
| 112 |
+
"normalized": false,
|
| 113 |
+
"rstrip": false,
|
| 114 |
+
"single_word": false,
|
| 115 |
+
"special": false
|
| 116 |
+
},
|
| 117 |
+
"156905": {
|
| 118 |
+
"content": "<arg_key>",
|
| 119 |
+
"lstrip": false,
|
| 120 |
+
"normalized": false,
|
| 121 |
+
"rstrip": false,
|
| 122 |
+
"single_word": false,
|
| 123 |
+
"special": false
|
| 124 |
+
},
|
| 125 |
+
"156906": {
|
| 126 |
+
"content": "</arg_key>",
|
| 127 |
+
"lstrip": false,
|
| 128 |
+
"normalized": false,
|
| 129 |
+
"rstrip": false,
|
| 130 |
+
"single_word": false,
|
| 131 |
+
"special": false
|
| 132 |
+
},
|
| 133 |
+
"156907": {
|
| 134 |
+
"content": "<arg_value>",
|
| 135 |
+
"lstrip": false,
|
| 136 |
+
"normalized": false,
|
| 137 |
+
"rstrip": false,
|
| 138 |
+
"single_word": false,
|
| 139 |
+
"special": false
|
| 140 |
+
},
|
| 141 |
+
"156908": {
|
| 142 |
+
"content": "</arg_value>",
|
| 143 |
+
"lstrip": false,
|
| 144 |
+
"normalized": false,
|
| 145 |
+
"rstrip": false,
|
| 146 |
+
"single_word": false,
|
| 147 |
+
"special": false
|
| 148 |
+
},
|
| 149 |
+
"156909": {
|
| 150 |
+
"content": "<|reserved_token_14|>",
|
| 151 |
+
"lstrip": false,
|
| 152 |
+
"normalized": false,
|
| 153 |
+
"rstrip": false,
|
| 154 |
+
"single_word": false,
|
| 155 |
+
"special": true
|
| 156 |
+
},
|
| 157 |
+
"156910": {
|
| 158 |
+
"content": "<|reserved_token_15|>",
|
| 159 |
+
"lstrip": false,
|
| 160 |
+
"normalized": false,
|
| 161 |
+
"rstrip": false,
|
| 162 |
+
"single_word": false,
|
| 163 |
+
"special": true
|
| 164 |
+
},
|
| 165 |
+
"156911": {
|
| 166 |
+
"content": "<|reserved_token_16|>",
|
| 167 |
+
"lstrip": false,
|
| 168 |
+
"normalized": false,
|
| 169 |
+
"rstrip": false,
|
| 170 |
+
"single_word": false,
|
| 171 |
+
"special": true
|
| 172 |
+
},
|
| 173 |
+
"156912": {
|
| 174 |
+
"content": "<|reserved_token_17|>",
|
| 175 |
+
"lstrip": false,
|
| 176 |
+
"normalized": false,
|
| 177 |
+
"rstrip": false,
|
| 178 |
+
"single_word": false,
|
| 179 |
+
"special": true
|
| 180 |
+
},
|
| 181 |
+
"156913": {
|
| 182 |
+
"content": "<|reserved_token_18|>",
|
| 183 |
+
"lstrip": false,
|
| 184 |
+
"normalized": false,
|
| 185 |
+
"rstrip": false,
|
| 186 |
+
"single_word": false,
|
| 187 |
+
"special": true
|
| 188 |
+
},
|
| 189 |
+
"156914": {
|
| 190 |
+
"content": "<|reserved_token_19|>",
|
| 191 |
+
"lstrip": false,
|
| 192 |
+
"normalized": false,
|
| 193 |
+
"rstrip": false,
|
| 194 |
+
"single_word": false,
|
| 195 |
+
"special": true
|
| 196 |
+
},
|
| 197 |
+
"156915": {
|
| 198 |
+
"content": "<|reserved_token_20|>",
|
| 199 |
+
"lstrip": false,
|
| 200 |
+
"normalized": false,
|
| 201 |
+
"rstrip": false,
|
| 202 |
+
"single_word": false,
|
| 203 |
+
"special": true
|
| 204 |
+
},
|
| 205 |
+
"156916": {
|
| 206 |
+
"content": "<|reserved_token_21|>",
|
| 207 |
+
"lstrip": false,
|
| 208 |
+
"normalized": false,
|
| 209 |
+
"rstrip": false,
|
| 210 |
+
"single_word": false,
|
| 211 |
+
"special": true
|
| 212 |
+
},
|
| 213 |
+
"156917": {
|
| 214 |
+
"content": "<|reserved_token_22|>",
|
| 215 |
+
"lstrip": false,
|
| 216 |
+
"normalized": false,
|
| 217 |
+
"rstrip": false,
|
| 218 |
+
"single_word": false,
|
| 219 |
+
"special": true
|
| 220 |
+
},
|
| 221 |
+
"156918": {
|
| 222 |
+
"content": "<|reserved_token_23|>",
|
| 223 |
+
"lstrip": false,
|
| 224 |
+
"normalized": false,
|
| 225 |
+
"rstrip": false,
|
| 226 |
+
"single_word": false,
|
| 227 |
+
"special": true
|
| 228 |
+
},
|
| 229 |
+
"156919": {
|
| 230 |
+
"content": "<|reserved_token_24|>",
|
| 231 |
+
"lstrip": false,
|
| 232 |
+
"normalized": false,
|
| 233 |
+
"rstrip": false,
|
| 234 |
+
"single_word": false,
|
| 235 |
+
"special": true
|
| 236 |
+
},
|
| 237 |
+
"156920": {
|
| 238 |
+
"content": "<|reserved_token_25|>",
|
| 239 |
+
"lstrip": false,
|
| 240 |
+
"normalized": false,
|
| 241 |
+
"rstrip": false,
|
| 242 |
+
"single_word": false,
|
| 243 |
+
"special": true
|
| 244 |
+
},
|
| 245 |
+
"156921": {
|
| 246 |
+
"content": "<|reserved_token_26|>",
|
| 247 |
+
"lstrip": false,
|
| 248 |
+
"normalized": false,
|
| 249 |
+
"rstrip": false,
|
| 250 |
+
"single_word": false,
|
| 251 |
+
"special": true
|
| 252 |
+
},
|
| 253 |
+
"156922": {
|
| 254 |
+
"content": "<|reserved_token_27|>",
|
| 255 |
+
"lstrip": false,
|
| 256 |
+
"normalized": false,
|
| 257 |
+
"rstrip": false,
|
| 258 |
+
"single_word": false,
|
| 259 |
+
"special": true
|
| 260 |
+
},
|
| 261 |
+
"156923": {
|
| 262 |
+
"content": "<|reserved_token_28|>",
|
| 263 |
+
"lstrip": false,
|
| 264 |
+
"normalized": false,
|
| 265 |
+
"rstrip": false,
|
| 266 |
+
"single_word": false,
|
| 267 |
+
"special": true
|
| 268 |
+
},
|
| 269 |
+
"156924": {
|
| 270 |
+
"content": "<|reserved_token_29|>",
|
| 271 |
+
"lstrip": false,
|
| 272 |
+
"normalized": false,
|
| 273 |
+
"rstrip": false,
|
| 274 |
+
"single_word": false,
|
| 275 |
+
"special": true
|
| 276 |
+
},
|
| 277 |
+
"156925": {
|
| 278 |
+
"content": "<|reserved_token_30|>",
|
| 279 |
+
"lstrip": false,
|
| 280 |
+
"normalized": false,
|
| 281 |
+
"rstrip": false,
|
| 282 |
+
"single_word": false,
|
| 283 |
+
"special": true
|
| 284 |
+
},
|
| 285 |
+
"156926": {
|
| 286 |
+
"content": "<|reserved_token_31|>",
|
| 287 |
+
"lstrip": false,
|
| 288 |
+
"normalized": false,
|
| 289 |
+
"rstrip": false,
|
| 290 |
+
"single_word": false,
|
| 291 |
+
"special": true
|
| 292 |
+
},
|
| 293 |
+
"156927": {
|
| 294 |
+
"content": "<|reserved_token_32|>",
|
| 295 |
+
"lstrip": false,
|
| 296 |
+
"normalized": false,
|
| 297 |
+
"rstrip": false,
|
| 298 |
+
"single_word": false,
|
| 299 |
+
"special": true
|
| 300 |
+
},
|
| 301 |
+
"156928": {
|
| 302 |
+
"content": "<|reserved_token_33|>",
|
| 303 |
+
"lstrip": false,
|
| 304 |
+
"normalized": false,
|
| 305 |
+
"rstrip": false,
|
| 306 |
+
"single_word": false,
|
| 307 |
+
"special": true
|
| 308 |
+
},
|
| 309 |
+
"156929": {
|
| 310 |
+
"content": "<|reserved_token_34|>",
|
| 311 |
+
"lstrip": false,
|
| 312 |
+
"normalized": false,
|
| 313 |
+
"rstrip": false,
|
| 314 |
+
"single_word": false,
|
| 315 |
+
"special": true
|
| 316 |
+
},
|
| 317 |
+
"156930": {
|
| 318 |
+
"content": "<|reserved_token_35|>",
|
| 319 |
+
"lstrip": false,
|
| 320 |
+
"normalized": false,
|
| 321 |
+
"rstrip": false,
|
| 322 |
+
"single_word": false,
|
| 323 |
+
"special": true
|
| 324 |
+
},
|
| 325 |
+
"156931": {
|
| 326 |
+
"content": "<|reserved_token_36|>",
|
| 327 |
+
"lstrip": false,
|
| 328 |
+
"normalized": false,
|
| 329 |
+
"rstrip": false,
|
| 330 |
+
"single_word": false,
|
| 331 |
+
"special": true
|
| 332 |
+
},
|
| 333 |
+
"156932": {
|
| 334 |
+
"content": "<|reserved_token_37|>",
|
| 335 |
+
"lstrip": false,
|
| 336 |
+
"normalized": false,
|
| 337 |
+
"rstrip": false,
|
| 338 |
+
"single_word": false,
|
| 339 |
+
"special": true
|
| 340 |
+
},
|
| 341 |
+
"156933": {
|
| 342 |
+
"content": "<|reserved_token_38|>",
|
| 343 |
+
"lstrip": false,
|
| 344 |
+
"normalized": false,
|
| 345 |
+
"rstrip": false,
|
| 346 |
+
"single_word": false,
|
| 347 |
+
"special": true
|
| 348 |
+
},
|
| 349 |
+
"156934": {
|
| 350 |
+
"content": "<|reserved_token_39|>",
|
| 351 |
+
"lstrip": false,
|
| 352 |
+
"normalized": false,
|
| 353 |
+
"rstrip": false,
|
| 354 |
+
"single_word": false,
|
| 355 |
+
"special": true
|
| 356 |
+
},
|
| 357 |
+
"156935": {
|
| 358 |
+
"content": "<|reserved_token_40|>",
|
| 359 |
+
"lstrip": false,
|
| 360 |
+
"normalized": false,
|
| 361 |
+
"rstrip": false,
|
| 362 |
+
"single_word": false,
|
| 363 |
+
"special": true
|
| 364 |
+
},
|
| 365 |
+
"156936": {
|
| 366 |
+
"content": "<|reserved_token_41|>",
|
| 367 |
+
"lstrip": false,
|
| 368 |
+
"normalized": false,
|
| 369 |
+
"rstrip": false,
|
| 370 |
+
"single_word": false,
|
| 371 |
+
"special": true
|
| 372 |
+
},
|
| 373 |
+
"156937": {
|
| 374 |
+
"content": "<|reserved_token_42|>",
|
| 375 |
+
"lstrip": false,
|
| 376 |
+
"normalized": false,
|
| 377 |
+
"rstrip": false,
|
| 378 |
+
"single_word": false,
|
| 379 |
+
"special": true
|
| 380 |
+
},
|
| 381 |
+
"156938": {
|
| 382 |
+
"content": "<|reserved_token_43|>",
|
| 383 |
+
"lstrip": false,
|
| 384 |
+
"normalized": false,
|
| 385 |
+
"rstrip": false,
|
| 386 |
+
"single_word": false,
|
| 387 |
+
"special": true
|
| 388 |
+
},
|
| 389 |
+
"156939": {
|
| 390 |
+
"content": "<|reserved_token_44|>",
|
| 391 |
+
"lstrip": false,
|
| 392 |
+
"normalized": false,
|
| 393 |
+
"rstrip": false,
|
| 394 |
+
"single_word": false,
|
| 395 |
+
"special": true
|
| 396 |
+
},
|
| 397 |
+
"156940": {
|
| 398 |
+
"content": "<|reserved_token_45|>",
|
| 399 |
+
"lstrip": false,
|
| 400 |
+
"normalized": false,
|
| 401 |
+
"rstrip": false,
|
| 402 |
+
"single_word": false,
|
| 403 |
+
"special": true
|
| 404 |
+
},
|
| 405 |
+
"156941": {
|
| 406 |
+
"content": "<|reserved_token_46|>",
|
| 407 |
+
"lstrip": false,
|
| 408 |
+
"normalized": false,
|
| 409 |
+
"rstrip": false,
|
| 410 |
+
"single_word": false,
|
| 411 |
+
"special": true
|
| 412 |
+
},
|
| 413 |
+
"156942": {
|
| 414 |
+
"content": "<|reserved_token_47|>",
|
| 415 |
+
"lstrip": false,
|
| 416 |
+
"normalized": false,
|
| 417 |
+
"rstrip": false,
|
| 418 |
+
"single_word": false,
|
| 419 |
+
"special": true
|
| 420 |
+
},
|
| 421 |
+
"156943": {
|
| 422 |
+
"content": "<|reserved_token_48|>",
|
| 423 |
+
"lstrip": false,
|
| 424 |
+
"normalized": false,
|
| 425 |
+
"rstrip": false,
|
| 426 |
+
"single_word": false,
|
| 427 |
+
"special": true
|
| 428 |
+
},
|
| 429 |
+
"156944": {
|
| 430 |
+
"content": "<|reserved_token_49|>",
|
| 431 |
+
"lstrip": false,
|
| 432 |
+
"normalized": false,
|
| 433 |
+
"rstrip": false,
|
| 434 |
+
"single_word": false,
|
| 435 |
+
"special": true
|
| 436 |
+
},
|
| 437 |
+
"156945": {
|
| 438 |
+
"content": "<|reserved_token_50|>",
|
| 439 |
+
"lstrip": false,
|
| 440 |
+
"normalized": false,
|
| 441 |
+
"rstrip": false,
|
| 442 |
+
"single_word": false,
|
| 443 |
+
"special": true
|
| 444 |
+
},
|
| 445 |
+
"156946": {
|
| 446 |
+
"content": "<|reserved_token_51|>",
|
| 447 |
+
"lstrip": false,
|
| 448 |
+
"normalized": false,
|
| 449 |
+
"rstrip": false,
|
| 450 |
+
"single_word": false,
|
| 451 |
+
"special": true
|
| 452 |
+
},
|
| 453 |
+
"156947": {
|
| 454 |
+
"content": "<|reserved_token_52|>",
|
| 455 |
+
"lstrip": false,
|
| 456 |
+
"normalized": false,
|
| 457 |
+
"rstrip": false,
|
| 458 |
+
"single_word": false,
|
| 459 |
+
"special": true
|
| 460 |
+
},
|
| 461 |
+
"156948": {
|
| 462 |
+
"content": "<|reserved_token_53|>",
|
| 463 |
+
"lstrip": false,
|
| 464 |
+
"normalized": false,
|
| 465 |
+
"rstrip": false,
|
| 466 |
+
"single_word": false,
|
| 467 |
+
"special": true
|
| 468 |
+
},
|
| 469 |
+
"156949": {
|
| 470 |
+
"content": "<|reserved_token_54|>",
|
| 471 |
+
"lstrip": false,
|
| 472 |
+
"normalized": false,
|
| 473 |
+
"rstrip": false,
|
| 474 |
+
"single_word": false,
|
| 475 |
+
"special": true
|
| 476 |
+
},
|
| 477 |
+
"156950": {
|
| 478 |
+
"content": "<|reserved_token_55|>",
|
| 479 |
+
"lstrip": false,
|
| 480 |
+
"normalized": false,
|
| 481 |
+
"rstrip": false,
|
| 482 |
+
"single_word": false,
|
| 483 |
+
"special": true
|
| 484 |
+
},
|
| 485 |
+
"156951": {
|
| 486 |
+
"content": "<|reserved_token_56|>",
|
| 487 |
+
"lstrip": false,
|
| 488 |
+
"normalized": false,
|
| 489 |
+
"rstrip": false,
|
| 490 |
+
"single_word": false,
|
| 491 |
+
"special": true
|
| 492 |
+
},
|
| 493 |
+
"156952": {
|
| 494 |
+
"content": "<|reserved_token_57|>",
|
| 495 |
+
"lstrip": false,
|
| 496 |
+
"normalized": false,
|
| 497 |
+
"rstrip": false,
|
| 498 |
+
"single_word": false,
|
| 499 |
+
"special": true
|
| 500 |
+
},
|
| 501 |
+
"156953": {
|
| 502 |
+
"content": "<|reserved_token_58|>",
|
| 503 |
+
"lstrip": false,
|
| 504 |
+
"normalized": false,
|
| 505 |
+
"rstrip": false,
|
| 506 |
+
"single_word": false,
|
| 507 |
+
"special": true
|
| 508 |
+
},
|
| 509 |
+
"156954": {
|
| 510 |
+
"content": "<|reserved_token_59|>",
|
| 511 |
+
"lstrip": false,
|
| 512 |
+
"normalized": false,
|
| 513 |
+
"rstrip": false,
|
| 514 |
+
"single_word": false,
|
| 515 |
+
"special": true
|
| 516 |
+
},
|
| 517 |
+
"156955": {
|
| 518 |
+
"content": "<|reserved_token_60|>",
|
| 519 |
+
"lstrip": false,
|
| 520 |
+
"normalized": false,
|
| 521 |
+
"rstrip": false,
|
| 522 |
+
"single_word": false,
|
| 523 |
+
"special": true
|
| 524 |
+
},
|
| 525 |
+
"156956": {
|
| 526 |
+
"content": "<|reserved_token_61|>",
|
| 527 |
+
"lstrip": false,
|
| 528 |
+
"normalized": false,
|
| 529 |
+
"rstrip": false,
|
| 530 |
+
"single_word": false,
|
| 531 |
+
"special": true
|
| 532 |
+
},
|
| 533 |
+
"156957": {
|
| 534 |
+
"content": "<|reserved_token_62|>",
|
| 535 |
+
"lstrip": false,
|
| 536 |
+
"normalized": false,
|
| 537 |
+
"rstrip": false,
|
| 538 |
+
"single_word": false,
|
| 539 |
+
"special": true
|
| 540 |
+
},
|
| 541 |
+
"156958": {
|
| 542 |
+
"content": "<|reserved_token_63|>",
|
| 543 |
+
"lstrip": false,
|
| 544 |
+
"normalized": false,
|
| 545 |
+
"rstrip": false,
|
| 546 |
+
"single_word": false,
|
| 547 |
+
"special": true
|
| 548 |
+
},
|
| 549 |
+
"156959": {
|
| 550 |
+
"content": "<|reserved_token_64|>",
|
| 551 |
+
"lstrip": false,
|
| 552 |
+
"normalized": false,
|
| 553 |
+
"rstrip": false,
|
| 554 |
+
"single_word": false,
|
| 555 |
+
"special": true
|
| 556 |
+
},
|
| 557 |
+
"156960": {
|
| 558 |
+
"content": "<|reserved_token_65|>",
|
| 559 |
+
"lstrip": false,
|
| 560 |
+
"normalized": false,
|
| 561 |
+
"rstrip": false,
|
| 562 |
+
"single_word": false,
|
| 563 |
+
"special": true
|
| 564 |
+
},
|
| 565 |
+
"156961": {
|
| 566 |
+
"content": "<|reserved_token_66|>",
|
| 567 |
+
"lstrip": false,
|
| 568 |
+
"normalized": false,
|
| 569 |
+
"rstrip": false,
|
| 570 |
+
"single_word": false,
|
| 571 |
+
"special": true
|
| 572 |
+
},
|
| 573 |
+
"156962": {
|
| 574 |
+
"content": "<|reserved_token_67|>",
|
| 575 |
+
"lstrip": false,
|
| 576 |
+
"normalized": false,
|
| 577 |
+
"rstrip": false,
|
| 578 |
+
"single_word": false,
|
| 579 |
+
"special": true
|
| 580 |
+
},
|
| 581 |
+
"156963": {
|
| 582 |
+
"content": "<|reserved_token_68|>",
|
| 583 |
+
"lstrip": false,
|
| 584 |
+
"normalized": false,
|
| 585 |
+
"rstrip": false,
|
| 586 |
+
"single_word": false,
|
| 587 |
+
"special": true
|
| 588 |
+
},
|
| 589 |
+
"156964": {
|
| 590 |
+
"content": "<|reserved_token_69|>",
|
| 591 |
+
"lstrip": false,
|
| 592 |
+
"normalized": false,
|
| 593 |
+
"rstrip": false,
|
| 594 |
+
"single_word": false,
|
| 595 |
+
"special": true
|
| 596 |
+
},
|
| 597 |
+
"156965": {
|
| 598 |
+
"content": "<|reserved_token_70|>",
|
| 599 |
+
"lstrip": false,
|
| 600 |
+
"normalized": false,
|
| 601 |
+
"rstrip": false,
|
| 602 |
+
"single_word": false,
|
| 603 |
+
"special": true
|
| 604 |
+
},
|
| 605 |
+
"156966": {
|
| 606 |
+
"content": "<|reserved_token_71|>",
|
| 607 |
+
"lstrip": false,
|
| 608 |
+
"normalized": false,
|
| 609 |
+
"rstrip": false,
|
| 610 |
+
"single_word": false,
|
| 611 |
+
"special": true
|
| 612 |
+
},
|
| 613 |
+
"156967": {
|
| 614 |
+
"content": "<|reserved_token_72|>",
|
| 615 |
+
"lstrip": false,
|
| 616 |
+
"normalized": false,
|
| 617 |
+
"rstrip": false,
|
| 618 |
+
"single_word": false,
|
| 619 |
+
"special": true
|
| 620 |
+
},
|
| 621 |
+
"156968": {
|
| 622 |
+
"content": "<|reserved_token_73|>",
|
| 623 |
+
"lstrip": false,
|
| 624 |
+
"normalized": false,
|
| 625 |
+
"rstrip": false,
|
| 626 |
+
"single_word": false,
|
| 627 |
+
"special": true
|
| 628 |
+
},
|
| 629 |
+
"156969": {
|
| 630 |
+
"content": "<|reserved_token_74|>",
|
| 631 |
+
"lstrip": false,
|
| 632 |
+
"normalized": false,
|
| 633 |
+
"rstrip": false,
|
| 634 |
+
"single_word": false,
|
| 635 |
+
"special": true
|
| 636 |
+
},
|
| 637 |
+
"156970": {
|
| 638 |
+
"content": "<|reserved_token_75|>",
|
| 639 |
+
"lstrip": false,
|
| 640 |
+
"normalized": false,
|
| 641 |
+
"rstrip": false,
|
| 642 |
+
"single_word": false,
|
| 643 |
+
"special": true
|
| 644 |
+
},
|
| 645 |
+
"156971": {
|
| 646 |
+
"content": "<|reserved_token_76|>",
|
| 647 |
+
"lstrip": false,
|
| 648 |
+
"normalized": false,
|
| 649 |
+
"rstrip": false,
|
| 650 |
+
"single_word": false,
|
| 651 |
+
"special": true
|
| 652 |
+
},
|
| 653 |
+
"156972": {
|
| 654 |
+
"content": "<|reserved_token_77|>",
|
| 655 |
+
"lstrip": false,
|
| 656 |
+
"normalized": false,
|
| 657 |
+
"rstrip": false,
|
| 658 |
+
"single_word": false,
|
| 659 |
+
"special": true
|
| 660 |
+
},
|
| 661 |
+
"156973": {
|
| 662 |
+
"content": "<|reserved_token_78|>",
|
| 663 |
+
"lstrip": false,
|
| 664 |
+
"normalized": false,
|
| 665 |
+
"rstrip": false,
|
| 666 |
+
"single_word": false,
|
| 667 |
+
"special": true
|
| 668 |
+
},
|
| 669 |
+
"156974": {
|
| 670 |
+
"content": "<|reserved_token_79|>",
|
| 671 |
+
"lstrip": false,
|
| 672 |
+
"normalized": false,
|
| 673 |
+
"rstrip": false,
|
| 674 |
+
"single_word": false,
|
| 675 |
+
"special": true
|
| 676 |
+
},
|
| 677 |
+
"156975": {
|
| 678 |
+
"content": "<|reserved_token_80|>",
|
| 679 |
+
"lstrip": false,
|
| 680 |
+
"normalized": false,
|
| 681 |
+
"rstrip": false,
|
| 682 |
+
"single_word": false,
|
| 683 |
+
"special": true
|
| 684 |
+
},
|
| 685 |
+
"156976": {
|
| 686 |
+
"content": "<|reserved_token_81|>",
|
| 687 |
+
"lstrip": false,
|
| 688 |
+
"normalized": false,
|
| 689 |
+
"rstrip": false,
|
| 690 |
+
"single_word": false,
|
| 691 |
+
"special": true
|
| 692 |
+
},
|
| 693 |
+
"156977": {
|
| 694 |
+
"content": "<|reserved_token_82|>",
|
| 695 |
+
"lstrip": false,
|
| 696 |
+
"normalized": false,
|
| 697 |
+
"rstrip": false,
|
| 698 |
+
"single_word": false,
|
| 699 |
+
"special": true
|
| 700 |
+
},
|
| 701 |
+
"156978": {
|
| 702 |
+
"content": "<|reserved_token_83|>",
|
| 703 |
+
"lstrip": false,
|
| 704 |
+
"normalized": false,
|
| 705 |
+
"rstrip": false,
|
| 706 |
+
"single_word": false,
|
| 707 |
+
"special": true
|
| 708 |
+
},
|
| 709 |
+
"156979": {
|
| 710 |
+
"content": "<|reserved_token_84|>",
|
| 711 |
+
"lstrip": false,
|
| 712 |
+
"normalized": false,
|
| 713 |
+
"rstrip": false,
|
| 714 |
+
"single_word": false,
|
| 715 |
+
"special": true
|
| 716 |
+
},
|
| 717 |
+
"156980": {
|
| 718 |
+
"content": "<|reserved_token_85|>",
|
| 719 |
+
"lstrip": false,
|
| 720 |
+
"normalized": false,
|
| 721 |
+
"rstrip": false,
|
| 722 |
+
"single_word": false,
|
| 723 |
+
"special": true
|
| 724 |
+
},
|
| 725 |
+
"156981": {
|
| 726 |
+
"content": "<|reserved_token_86|>",
|
| 727 |
+
"lstrip": false,
|
| 728 |
+
"normalized": false,
|
| 729 |
+
"rstrip": false,
|
| 730 |
+
"single_word": false,
|
| 731 |
+
"special": true
|
| 732 |
+
},
|
| 733 |
+
"156982": {
|
| 734 |
+
"content": "<|reserved_token_87|>",
|
| 735 |
+
"lstrip": false,
|
| 736 |
+
"normalized": false,
|
| 737 |
+
"rstrip": false,
|
| 738 |
+
"single_word": false,
|
| 739 |
+
"special": true
|
| 740 |
+
},
|
| 741 |
+
"156983": {
|
| 742 |
+
"content": "<|reserved_token_88|>",
|
| 743 |
+
"lstrip": false,
|
| 744 |
+
"normalized": false,
|
| 745 |
+
"rstrip": false,
|
| 746 |
+
"single_word": false,
|
| 747 |
+
"special": true
|
| 748 |
+
},
|
| 749 |
+
"156984": {
|
| 750 |
+
"content": "<|reserved_token_89|>",
|
| 751 |
+
"lstrip": false,
|
| 752 |
+
"normalized": false,
|
| 753 |
+
"rstrip": false,
|
| 754 |
+
"single_word": false,
|
| 755 |
+
"special": true
|
| 756 |
+
},
|
| 757 |
+
"156985": {
|
| 758 |
+
"content": "<|reserved_token_90|>",
|
| 759 |
+
"lstrip": false,
|
| 760 |
+
"normalized": false,
|
| 761 |
+
"rstrip": false,
|
| 762 |
+
"single_word": false,
|
| 763 |
+
"special": true
|
| 764 |
+
},
|
| 765 |
+
"156986": {
|
| 766 |
+
"content": "<|reserved_token_91|>",
|
| 767 |
+
"lstrip": false,
|
| 768 |
+
"normalized": false,
|
| 769 |
+
"rstrip": false,
|
| 770 |
+
"single_word": false,
|
| 771 |
+
"special": true
|
| 772 |
+
},
|
| 773 |
+
"156987": {
|
| 774 |
+
"content": "<|reserved_token_92|>",
|
| 775 |
+
"lstrip": false,
|
| 776 |
+
"normalized": false,
|
| 777 |
+
"rstrip": false,
|
| 778 |
+
"single_word": false,
|
| 779 |
+
"special": true
|
| 780 |
+
},
|
| 781 |
+
"156988": {
|
| 782 |
+
"content": "<|reserved_token_93|>",
|
| 783 |
+
"lstrip": false,
|
| 784 |
+
"normalized": false,
|
| 785 |
+
"rstrip": false,
|
| 786 |
+
"single_word": false,
|
| 787 |
+
"special": true
|
| 788 |
+
},
|
| 789 |
+
"156989": {
|
| 790 |
+
"content": "<|reserved_token_94|>",
|
| 791 |
+
"lstrip": false,
|
| 792 |
+
"normalized": false,
|
| 793 |
+
"rstrip": false,
|
| 794 |
+
"single_word": false,
|
| 795 |
+
"special": true
|
| 796 |
+
},
|
| 797 |
+
"156990": {
|
| 798 |
+
"content": "<|reserved_token_95|>",
|
| 799 |
+
"lstrip": false,
|
| 800 |
+
"normalized": false,
|
| 801 |
+
"rstrip": false,
|
| 802 |
+
"single_word": false,
|
| 803 |
+
"special": true
|
| 804 |
+
},
|
| 805 |
+
"156991": {
|
| 806 |
+
"content": "<|reserved_token_96|>",
|
| 807 |
+
"lstrip": false,
|
| 808 |
+
"normalized": false,
|
| 809 |
+
"rstrip": false,
|
| 810 |
+
"single_word": false,
|
| 811 |
+
"special": true
|
| 812 |
+
},
|
| 813 |
+
"156992": {
|
| 814 |
+
"content": "<|reserved_token_97|>",
|
| 815 |
+
"lstrip": false,
|
| 816 |
+
"normalized": false,
|
| 817 |
+
"rstrip": false,
|
| 818 |
+
"single_word": false,
|
| 819 |
+
"special": true
|
| 820 |
+
},
|
| 821 |
+
"156993": {
|
| 822 |
+
"content": "<|reserved_token_98|>",
|
| 823 |
+
"lstrip": false,
|
| 824 |
+
"normalized": false,
|
| 825 |
+
"rstrip": false,
|
| 826 |
+
"single_word": false,
|
| 827 |
+
"special": true
|
| 828 |
+
},
|
| 829 |
+
"156994": {
|
| 830 |
+
"content": "<|reserved_token_99|>",
|
| 831 |
+
"lstrip": false,
|
| 832 |
+
"normalized": false,
|
| 833 |
+
"rstrip": false,
|
| 834 |
+
"single_word": false,
|
| 835 |
+
"special": true
|
| 836 |
+
},
|
| 837 |
+
"156995": {
|
| 838 |
+
"content": "<|reserved_token_100|>",
|
| 839 |
+
"lstrip": false,
|
| 840 |
+
"normalized": false,
|
| 841 |
+
"rstrip": false,
|
| 842 |
+
"single_word": false,
|
| 843 |
+
"special": true
|
| 844 |
+
},
|
| 845 |
+
"156996": {
|
| 846 |
+
"content": "<|reserved_token_101|>",
|
| 847 |
+
"lstrip": false,
|
| 848 |
+
"normalized": false,
|
| 849 |
+
"rstrip": false,
|
| 850 |
+
"single_word": false,
|
| 851 |
+
"special": true
|
| 852 |
+
},
|
| 853 |
+
"156997": {
|
| 854 |
+
"content": "<|reserved_token_102|>",
|
| 855 |
+
"lstrip": false,
|
| 856 |
+
"normalized": false,
|
| 857 |
+
"rstrip": false,
|
| 858 |
+
"single_word": false,
|
| 859 |
+
"special": true
|
| 860 |
+
},
|
| 861 |
+
"156998": {
|
| 862 |
+
"content": "<|reserved_token_103|>",
|
| 863 |
+
"lstrip": false,
|
| 864 |
+
"normalized": false,
|
| 865 |
+
"rstrip": false,
|
| 866 |
+
"single_word": false,
|
| 867 |
+
"special": true
|
| 868 |
+
},
|
| 869 |
+
"156999": {
|
| 870 |
+
"content": "<|reserved_token_104|>",
|
| 871 |
+
"lstrip": false,
|
| 872 |
+
"normalized": false,
|
| 873 |
+
"rstrip": false,
|
| 874 |
+
"single_word": false,
|
| 875 |
+
"special": true
|
| 876 |
+
},
|
| 877 |
+
"157000": {
|
| 878 |
+
"content": "<|reserved_token_105|>",
|
| 879 |
+
"lstrip": false,
|
| 880 |
+
"normalized": false,
|
| 881 |
+
"rstrip": false,
|
| 882 |
+
"single_word": false,
|
| 883 |
+
"special": true
|
| 884 |
+
},
|
| 885 |
+
"157001": {
|
| 886 |
+
"content": "<|reserved_token_106|>",
|
| 887 |
+
"lstrip": false,
|
| 888 |
+
"normalized": false,
|
| 889 |
+
"rstrip": false,
|
| 890 |
+
"single_word": false,
|
| 891 |
+
"special": true
|
| 892 |
+
},
|
| 893 |
+
"157002": {
|
| 894 |
+
"content": "<|reserved_token_107|>",
|
| 895 |
+
"lstrip": false,
|
| 896 |
+
"normalized": false,
|
| 897 |
+
"rstrip": false,
|
| 898 |
+
"single_word": false,
|
| 899 |
+
"special": true
|
| 900 |
+
},
|
| 901 |
+
"157003": {
|
| 902 |
+
"content": "<|reserved_token_108|>",
|
| 903 |
+
"lstrip": false,
|
| 904 |
+
"normalized": false,
|
| 905 |
+
"rstrip": false,
|
| 906 |
+
"single_word": false,
|
| 907 |
+
"special": true
|
| 908 |
+
},
|
| 909 |
+
"157004": {
|
| 910 |
+
"content": "<|reserved_token_109|>",
|
| 911 |
+
"lstrip": false,
|
| 912 |
+
"normalized": false,
|
| 913 |
+
"rstrip": false,
|
| 914 |
+
"single_word": false,
|
| 915 |
+
"special": true
|
| 916 |
+
},
|
| 917 |
+
"157005": {
|
| 918 |
+
"content": "<|reserved_token_110|>",
|
| 919 |
+
"lstrip": false,
|
| 920 |
+
"normalized": false,
|
| 921 |
+
"rstrip": false,
|
| 922 |
+
"single_word": false,
|
| 923 |
+
"special": true
|
| 924 |
+
},
|
| 925 |
+
"157006": {
|
| 926 |
+
"content": "<|reserved_token_111|>",
|
| 927 |
+
"lstrip": false,
|
| 928 |
+
"normalized": false,
|
| 929 |
+
"rstrip": false,
|
| 930 |
+
"single_word": false,
|
| 931 |
+
"special": true
|
| 932 |
+
},
|
| 933 |
+
"157007": {
|
| 934 |
+
"content": "<|reserved_token_112|>",
|
| 935 |
+
"lstrip": false,
|
| 936 |
+
"normalized": false,
|
| 937 |
+
"rstrip": false,
|
| 938 |
+
"single_word": false,
|
| 939 |
+
"special": true
|
| 940 |
+
},
|
| 941 |
+
"157008": {
|
| 942 |
+
"content": "<|reserved_token_113|>",
|
| 943 |
+
"lstrip": false,
|
| 944 |
+
"normalized": false,
|
| 945 |
+
"rstrip": false,
|
| 946 |
+
"single_word": false,
|
| 947 |
+
"special": true
|
| 948 |
+
},
|
| 949 |
+
"157009": {
|
| 950 |
+
"content": "<|reserved_token_114|>",
|
| 951 |
+
"lstrip": false,
|
| 952 |
+
"normalized": false,
|
| 953 |
+
"rstrip": false,
|
| 954 |
+
"single_word": false,
|
| 955 |
+
"special": true
|
| 956 |
+
},
|
| 957 |
+
"157010": {
|
| 958 |
+
"content": "<|reserved_token_115|>",
|
| 959 |
+
"lstrip": false,
|
| 960 |
+
"normalized": false,
|
| 961 |
+
"rstrip": false,
|
| 962 |
+
"single_word": false,
|
| 963 |
+
"special": true
|
| 964 |
+
},
|
| 965 |
+
"157011": {
|
| 966 |
+
"content": "<|reserved_token_116|>",
|
| 967 |
+
"lstrip": false,
|
| 968 |
+
"normalized": false,
|
| 969 |
+
"rstrip": false,
|
| 970 |
+
"single_word": false,
|
| 971 |
+
"special": true
|
| 972 |
+
},
|
| 973 |
+
"157012": {
|
| 974 |
+
"content": "<|reserved_token_117|>",
|
| 975 |
+
"lstrip": false,
|
| 976 |
+
"normalized": false,
|
| 977 |
+
"rstrip": false,
|
| 978 |
+
"single_word": false,
|
| 979 |
+
"special": true
|
| 980 |
+
},
|
| 981 |
+
"157013": {
|
| 982 |
+
"content": "<|reserved_token_118|>",
|
| 983 |
+
"lstrip": false,
|
| 984 |
+
"normalized": false,
|
| 985 |
+
"rstrip": false,
|
| 986 |
+
"single_word": false,
|
| 987 |
+
"special": true
|
| 988 |
+
},
|
| 989 |
+
"157014": {
|
| 990 |
+
"content": "<|reserved_token_119|>",
|
| 991 |
+
"lstrip": false,
|
| 992 |
+
"normalized": false,
|
| 993 |
+
"rstrip": false,
|
| 994 |
+
"single_word": false,
|
| 995 |
+
"special": true
|
| 996 |
+
},
|
| 997 |
+
"157015": {
|
| 998 |
+
"content": "<|reserved_token_120|>",
|
| 999 |
+
"lstrip": false,
|
| 1000 |
+
"normalized": false,
|
| 1001 |
+
"rstrip": false,
|
| 1002 |
+
"single_word": false,
|
| 1003 |
+
"special": true
|
| 1004 |
+
},
|
| 1005 |
+
"157016": {
|
| 1006 |
+
"content": "<|reserved_token_121|>",
|
| 1007 |
+
"lstrip": false,
|
| 1008 |
+
"normalized": false,
|
| 1009 |
+
"rstrip": false,
|
| 1010 |
+
"single_word": false,
|
| 1011 |
+
"special": true
|
| 1012 |
+
},
|
| 1013 |
+
"157017": {
|
| 1014 |
+
"content": "<|reserved_token_122|>",
|
| 1015 |
+
"lstrip": false,
|
| 1016 |
+
"normalized": false,
|
| 1017 |
+
"rstrip": false,
|
| 1018 |
+
"single_word": false,
|
| 1019 |
+
"special": true
|
| 1020 |
+
},
|
| 1021 |
+
"157018": {
|
| 1022 |
+
"content": "<|reserved_token_123|>",
|
| 1023 |
+
"lstrip": false,
|
| 1024 |
+
"normalized": false,
|
| 1025 |
+
"rstrip": false,
|
| 1026 |
+
"single_word": false,
|
| 1027 |
+
"special": true
|
| 1028 |
+
},
|
| 1029 |
+
"157019": {
|
| 1030 |
+
"content": "<|reserved_token_124|>",
|
| 1031 |
+
"lstrip": false,
|
| 1032 |
+
"normalized": false,
|
| 1033 |
+
"rstrip": false,
|
| 1034 |
+
"single_word": false,
|
| 1035 |
+
"special": true
|
| 1036 |
+
},
|
| 1037 |
+
"157020": {
|
| 1038 |
+
"content": "<|reserved_token_125|>",
|
| 1039 |
+
"lstrip": false,
|
| 1040 |
+
"normalized": false,
|
| 1041 |
+
"rstrip": false,
|
| 1042 |
+
"single_word": false,
|
| 1043 |
+
"special": true
|
| 1044 |
+
},
|
| 1045 |
+
"157021": {
|
| 1046 |
+
"content": "<|reserved_token_126|>",
|
| 1047 |
+
"lstrip": false,
|
| 1048 |
+
"normalized": false,
|
| 1049 |
+
"rstrip": false,
|
| 1050 |
+
"single_word": false,
|
| 1051 |
+
"special": true
|
| 1052 |
+
},
|
| 1053 |
+
"157022": {
|
| 1054 |
+
"content": "<|reserved_token_127|>",
|
| 1055 |
+
"lstrip": false,
|
| 1056 |
+
"normalized": false,
|
| 1057 |
+
"rstrip": false,
|
| 1058 |
+
"single_word": false,
|
| 1059 |
+
"special": true
|
| 1060 |
+
},
|
| 1061 |
+
"157023": {
|
| 1062 |
+
"content": "<|reserved_token_128|>",
|
| 1063 |
+
"lstrip": false,
|
| 1064 |
+
"normalized": false,
|
| 1065 |
+
"rstrip": false,
|
| 1066 |
+
"single_word": false,
|
| 1067 |
+
"special": true
|
| 1068 |
+
},
|
| 1069 |
+
"157024": {
|
| 1070 |
+
"content": "<|reserved_token_129|>",
|
| 1071 |
+
"lstrip": false,
|
| 1072 |
+
"normalized": false,
|
| 1073 |
+
"rstrip": false,
|
| 1074 |
+
"single_word": false,
|
| 1075 |
+
"special": true
|
| 1076 |
+
},
|
| 1077 |
+
"157025": {
|
| 1078 |
+
"content": "<|reserved_token_130|>",
|
| 1079 |
+
"lstrip": false,
|
| 1080 |
+
"normalized": false,
|
| 1081 |
+
"rstrip": false,
|
| 1082 |
+
"single_word": false,
|
| 1083 |
+
"special": true
|
| 1084 |
+
},
|
| 1085 |
+
"157026": {
|
| 1086 |
+
"content": "<|reserved_token_131|>",
|
| 1087 |
+
"lstrip": false,
|
| 1088 |
+
"normalized": false,
|
| 1089 |
+
"rstrip": false,
|
| 1090 |
+
"single_word": false,
|
| 1091 |
+
"special": true
|
| 1092 |
+
},
|
| 1093 |
+
"157027": {
|
| 1094 |
+
"content": "<|reserved_token_132|>",
|
| 1095 |
+
"lstrip": false,
|
| 1096 |
+
"normalized": false,
|
| 1097 |
+
"rstrip": false,
|
| 1098 |
+
"single_word": false,
|
| 1099 |
+
"special": true
|
| 1100 |
+
},
|
| 1101 |
+
"157028": {
|
| 1102 |
+
"content": "<|reserved_token_133|>",
|
| 1103 |
+
"lstrip": false,
|
| 1104 |
+
"normalized": false,
|
| 1105 |
+
"rstrip": false,
|
| 1106 |
+
"single_word": false,
|
| 1107 |
+
"special": true
|
| 1108 |
+
},
|
| 1109 |
+
"157029": {
|
| 1110 |
+
"content": "<|reserved_token_134|>",
|
| 1111 |
+
"lstrip": false,
|
| 1112 |
+
"normalized": false,
|
| 1113 |
+
"rstrip": false,
|
| 1114 |
+
"single_word": false,
|
| 1115 |
+
"special": true
|
| 1116 |
+
},
|
| 1117 |
+
"157030": {
|
| 1118 |
+
"content": "<|reserved_token_135|>",
|
| 1119 |
+
"lstrip": false,
|
| 1120 |
+
"normalized": false,
|
| 1121 |
+
"rstrip": false,
|
| 1122 |
+
"single_word": false,
|
| 1123 |
+
"special": true
|
| 1124 |
+
},
|
| 1125 |
+
"157031": {
|
| 1126 |
+
"content": "<|reserved_token_136|>",
|
| 1127 |
+
"lstrip": false,
|
| 1128 |
+
"normalized": false,
|
| 1129 |
+
"rstrip": false,
|
| 1130 |
+
"single_word": false,
|
| 1131 |
+
"special": true
|
| 1132 |
+
},
|
| 1133 |
+
"157032": {
|
| 1134 |
+
"content": "<|reserved_token_137|>",
|
| 1135 |
+
"lstrip": false,
|
| 1136 |
+
"normalized": false,
|
| 1137 |
+
"rstrip": false,
|
| 1138 |
+
"single_word": false,
|
| 1139 |
+
"special": true
|
| 1140 |
+
},
|
| 1141 |
+
"157033": {
|
| 1142 |
+
"content": "<|reserved_token_138|>",
|
| 1143 |
+
"lstrip": false,
|
| 1144 |
+
"normalized": false,
|
| 1145 |
+
"rstrip": false,
|
| 1146 |
+
"single_word": false,
|
| 1147 |
+
"special": true
|
| 1148 |
+
},
|
| 1149 |
+
"157034": {
|
| 1150 |
+
"content": "<|reserved_token_139|>",
|
| 1151 |
+
"lstrip": false,
|
| 1152 |
+
"normalized": false,
|
| 1153 |
+
"rstrip": false,
|
| 1154 |
+
"single_word": false,
|
| 1155 |
+
"special": true
|
| 1156 |
+
},
|
| 1157 |
+
"157035": {
|
| 1158 |
+
"content": "<|reserved_token_140|>",
|
| 1159 |
+
"lstrip": false,
|
| 1160 |
+
"normalized": false,
|
| 1161 |
+
"rstrip": false,
|
| 1162 |
+
"single_word": false,
|
| 1163 |
+
"special": true
|
| 1164 |
+
},
|
| 1165 |
+
"157036": {
|
| 1166 |
+
"content": "<|reserved_token_141|>",
|
| 1167 |
+
"lstrip": false,
|
| 1168 |
+
"normalized": false,
|
| 1169 |
+
"rstrip": false,
|
| 1170 |
+
"single_word": false,
|
| 1171 |
+
"special": true
|
| 1172 |
+
},
|
| 1173 |
+
"157037": {
|
| 1174 |
+
"content": "<|reserved_token_142|>",
|
| 1175 |
+
"lstrip": false,
|
| 1176 |
+
"normalized": false,
|
| 1177 |
+
"rstrip": false,
|
| 1178 |
+
"single_word": false,
|
| 1179 |
+
"special": true
|
| 1180 |
+
},
|
| 1181 |
+
"157038": {
|
| 1182 |
+
"content": "<|reserved_token_143|>",
|
| 1183 |
+
"lstrip": false,
|
| 1184 |
+
"normalized": false,
|
| 1185 |
+
"rstrip": false,
|
| 1186 |
+
"single_word": false,
|
| 1187 |
+
"special": true
|
| 1188 |
+
},
|
| 1189 |
+
"157039": {
|
| 1190 |
+
"content": "<|reserved_token_144|>",
|
| 1191 |
+
"lstrip": false,
|
| 1192 |
+
"normalized": false,
|
| 1193 |
+
"rstrip": false,
|
| 1194 |
+
"single_word": false,
|
| 1195 |
+
"special": true
|
| 1196 |
+
},
|
| 1197 |
+
"157040": {
|
| 1198 |
+
"content": "<|reserved_token_145|>",
|
| 1199 |
+
"lstrip": false,
|
| 1200 |
+
"normalized": false,
|
| 1201 |
+
"rstrip": false,
|
| 1202 |
+
"single_word": false,
|
| 1203 |
+
"special": true
|
| 1204 |
+
},
|
| 1205 |
+
"157041": {
|
| 1206 |
+
"content": "<|reserved_token_146|>",
|
| 1207 |
+
"lstrip": false,
|
| 1208 |
+
"normalized": false,
|
| 1209 |
+
"rstrip": false,
|
| 1210 |
+
"single_word": false,
|
| 1211 |
+
"special": true
|
| 1212 |
+
},
|
| 1213 |
+
"157042": {
|
| 1214 |
+
"content": "<|reserved_token_147|>",
|
| 1215 |
+
"lstrip": false,
|
| 1216 |
+
"normalized": false,
|
| 1217 |
+
"rstrip": false,
|
| 1218 |
+
"single_word": false,
|
| 1219 |
+
"special": true
|
| 1220 |
+
},
|
| 1221 |
+
"157043": {
|
| 1222 |
+
"content": "<|reserved_token_148|>",
|
| 1223 |
+
"lstrip": false,
|
| 1224 |
+
"normalized": false,
|
| 1225 |
+
"rstrip": false,
|
| 1226 |
+
"single_word": false,
|
| 1227 |
+
"special": true
|
| 1228 |
+
},
|
| 1229 |
+
"157044": {
|
| 1230 |
+
"content": "<|reserved_token_149|>",
|
| 1231 |
+
"lstrip": false,
|
| 1232 |
+
"normalized": false,
|
| 1233 |
+
"rstrip": false,
|
| 1234 |
+
"single_word": false,
|
| 1235 |
+
"special": true
|
| 1236 |
+
},
|
| 1237 |
+
"157045": {
|
| 1238 |
+
"content": "<|reserved_token_150|>",
|
| 1239 |
+
"lstrip": false,
|
| 1240 |
+
"normalized": false,
|
| 1241 |
+
"rstrip": false,
|
| 1242 |
+
"single_word": false,
|
| 1243 |
+
"special": true
|
| 1244 |
+
},
|
| 1245 |
+
"157046": {
|
| 1246 |
+
"content": "<|reserved_token_151|>",
|
| 1247 |
+
"lstrip": false,
|
| 1248 |
+
"normalized": false,
|
| 1249 |
+
"rstrip": false,
|
| 1250 |
+
"single_word": false,
|
| 1251 |
+
"special": true
|
| 1252 |
+
},
|
| 1253 |
+
"157047": {
|
| 1254 |
+
"content": "<|reserved_token_152|>",
|
| 1255 |
+
"lstrip": false,
|
| 1256 |
+
"normalized": false,
|
| 1257 |
+
"rstrip": false,
|
| 1258 |
+
"single_word": false,
|
| 1259 |
+
"special": true
|
| 1260 |
+
},
|
| 1261 |
+
"157048": {
|
| 1262 |
+
"content": "<|reserved_token_153|>",
|
| 1263 |
+
"lstrip": false,
|
| 1264 |
+
"normalized": false,
|
| 1265 |
+
"rstrip": false,
|
| 1266 |
+
"single_word": false,
|
| 1267 |
+
"special": true
|
| 1268 |
+
},
|
| 1269 |
+
"157049": {
|
| 1270 |
+
"content": "<|reserved_token_154|>",
|
| 1271 |
+
"lstrip": false,
|
| 1272 |
+
"normalized": false,
|
| 1273 |
+
"rstrip": false,
|
| 1274 |
+
"single_word": false,
|
| 1275 |
+
"special": true
|
| 1276 |
+
},
|
| 1277 |
+
"157050": {
|
| 1278 |
+
"content": "<|reserved_token_155|>",
|
| 1279 |
+
"lstrip": false,
|
| 1280 |
+
"normalized": false,
|
| 1281 |
+
"rstrip": false,
|
| 1282 |
+
"single_word": false,
|
| 1283 |
+
"special": true
|
| 1284 |
+
},
|
| 1285 |
+
"157051": {
|
| 1286 |
+
"content": "<|reserved_token_156|>",
|
| 1287 |
+
"lstrip": false,
|
| 1288 |
+
"normalized": false,
|
| 1289 |
+
"rstrip": false,
|
| 1290 |
+
"single_word": false,
|
| 1291 |
+
"special": true
|
| 1292 |
+
},
|
| 1293 |
+
"157052": {
|
| 1294 |
+
"content": "<|reserved_token_157|>",
|
| 1295 |
+
"lstrip": false,
|
| 1296 |
+
"normalized": false,
|
| 1297 |
+
"rstrip": false,
|
| 1298 |
+
"single_word": false,
|
| 1299 |
+
"special": true
|
| 1300 |
+
},
|
| 1301 |
+
"157053": {
|
| 1302 |
+
"content": "<|reserved_token_158|>",
|
| 1303 |
+
"lstrip": false,
|
| 1304 |
+
"normalized": false,
|
| 1305 |
+
"rstrip": false,
|
| 1306 |
+
"single_word": false,
|
| 1307 |
+
"special": true
|
| 1308 |
+
},
|
| 1309 |
+
"157054": {
|
| 1310 |
+
"content": "<|reserved_token_159|>",
|
| 1311 |
+
"lstrip": false,
|
| 1312 |
+
"normalized": false,
|
| 1313 |
+
"rstrip": false,
|
| 1314 |
+
"single_word": false,
|
| 1315 |
+
"special": true
|
| 1316 |
+
},
|
| 1317 |
+
"157055": {
|
| 1318 |
+
"content": "<|reserved_token_160|>",
|
| 1319 |
+
"lstrip": false,
|
| 1320 |
+
"normalized": false,
|
| 1321 |
+
"rstrip": false,
|
| 1322 |
+
"single_word": false,
|
| 1323 |
+
"special": true
|
| 1324 |
+
},
|
| 1325 |
+
"157056": {
|
| 1326 |
+
"content": "<|reserved_token_161|>",
|
| 1327 |
+
"lstrip": false,
|
| 1328 |
+
"normalized": false,
|
| 1329 |
+
"rstrip": false,
|
| 1330 |
+
"single_word": false,
|
| 1331 |
+
"special": true
|
| 1332 |
+
},
|
| 1333 |
+
"157057": {
|
| 1334 |
+
"content": "<|reserved_token_162|>",
|
| 1335 |
+
"lstrip": false,
|
| 1336 |
+
"normalized": false,
|
| 1337 |
+
"rstrip": false,
|
| 1338 |
+
"single_word": false,
|
| 1339 |
+
"special": true
|
| 1340 |
+
},
|
| 1341 |
+
"157058": {
|
| 1342 |
+
"content": "<|reserved_token_163|>",
|
| 1343 |
+
"lstrip": false,
|
| 1344 |
+
"normalized": false,
|
| 1345 |
+
"rstrip": false,
|
| 1346 |
+
"single_word": false,
|
| 1347 |
+
"special": true
|
| 1348 |
+
},
|
| 1349 |
+
"157059": {
|
| 1350 |
+
"content": "<|reserved_token_164|>",
|
| 1351 |
+
"lstrip": false,
|
| 1352 |
+
"normalized": false,
|
| 1353 |
+
"rstrip": false,
|
| 1354 |
+
"single_word": false,
|
| 1355 |
+
"special": true
|
| 1356 |
+
},
|
| 1357 |
+
"157060": {
|
| 1358 |
+
"content": "<|reserved_token_165|>",
|
| 1359 |
+
"lstrip": false,
|
| 1360 |
+
"normalized": false,
|
| 1361 |
+
"rstrip": false,
|
| 1362 |
+
"single_word": false,
|
| 1363 |
+
"special": true
|
| 1364 |
+
},
|
| 1365 |
+
"157061": {
|
| 1366 |
+
"content": "<|reserved_token_166|>",
|
| 1367 |
+
"lstrip": false,
|
| 1368 |
+
"normalized": false,
|
| 1369 |
+
"rstrip": false,
|
| 1370 |
+
"single_word": false,
|
| 1371 |
+
"special": true
|
| 1372 |
+
},
|
| 1373 |
+
"157062": {
|
| 1374 |
+
"content": "<|reserved_token_167|>",
|
| 1375 |
+
"lstrip": false,
|
| 1376 |
+
"normalized": false,
|
| 1377 |
+
"rstrip": false,
|
| 1378 |
+
"single_word": false,
|
| 1379 |
+
"special": true
|
| 1380 |
+
},
|
| 1381 |
+
"157063": {
|
| 1382 |
+
"content": "<|reserved_token_168|>",
|
| 1383 |
+
"lstrip": false,
|
| 1384 |
+
"normalized": false,
|
| 1385 |
+
"rstrip": false,
|
| 1386 |
+
"single_word": false,
|
| 1387 |
+
"special": true
|
| 1388 |
+
},
|
| 1389 |
+
"157064": {
|
| 1390 |
+
"content": "<|reserved_token_169|>",
|
| 1391 |
+
"lstrip": false,
|
| 1392 |
+
"normalized": false,
|
| 1393 |
+
"rstrip": false,
|
| 1394 |
+
"single_word": false,
|
| 1395 |
+
"special": true
|
| 1396 |
+
},
|
| 1397 |
+
"157065": {
|
| 1398 |
+
"content": "<|reserved_token_170|>",
|
| 1399 |
+
"lstrip": false,
|
| 1400 |
+
"normalized": false,
|
| 1401 |
+
"rstrip": false,
|
| 1402 |
+
"single_word": false,
|
| 1403 |
+
"special": true
|
| 1404 |
+
},
|
| 1405 |
+
"157066": {
|
| 1406 |
+
"content": "<|reserved_token_171|>",
|
| 1407 |
+
"lstrip": false,
|
| 1408 |
+
"normalized": false,
|
| 1409 |
+
"rstrip": false,
|
| 1410 |
+
"single_word": false,
|
| 1411 |
+
"special": true
|
| 1412 |
+
},
|
| 1413 |
+
"157067": {
|
| 1414 |
+
"content": "<|reserved_token_172|>",
|
| 1415 |
+
"lstrip": false,
|
| 1416 |
+
"normalized": false,
|
| 1417 |
+
"rstrip": false,
|
| 1418 |
+
"single_word": false,
|
| 1419 |
+
"special": true
|
| 1420 |
+
},
|
| 1421 |
+
"157068": {
|
| 1422 |
+
"content": "<|reserved_token_173|>",
|
| 1423 |
+
"lstrip": false,
|
| 1424 |
+
"normalized": false,
|
| 1425 |
+
"rstrip": false,
|
| 1426 |
+
"single_word": false,
|
| 1427 |
+
"special": true
|
| 1428 |
+
},
|
| 1429 |
+
"157069": {
|
| 1430 |
+
"content": "<|reserved_token_174|>",
|
| 1431 |
+
"lstrip": false,
|
| 1432 |
+
"normalized": false,
|
| 1433 |
+
"rstrip": false,
|
| 1434 |
+
"single_word": false,
|
| 1435 |
+
"special": true
|
| 1436 |
+
},
|
| 1437 |
+
"157070": {
|
| 1438 |
+
"content": "<|reserved_token_175|>",
|
| 1439 |
+
"lstrip": false,
|
| 1440 |
+
"normalized": false,
|
| 1441 |
+
"rstrip": false,
|
| 1442 |
+
"single_word": false,
|
| 1443 |
+
"special": true
|
| 1444 |
+
},
|
| 1445 |
+
"157071": {
|
| 1446 |
+
"content": "<|reserved_token_176|>",
|
| 1447 |
+
"lstrip": false,
|
| 1448 |
+
"normalized": false,
|
| 1449 |
+
"rstrip": false,
|
| 1450 |
+
"single_word": false,
|
| 1451 |
+
"special": true
|
| 1452 |
+
},
|
| 1453 |
+
"157072": {
|
| 1454 |
+
"content": "<|reserved_token_177|>",
|
| 1455 |
+
"lstrip": false,
|
| 1456 |
+
"normalized": false,
|
| 1457 |
+
"rstrip": false,
|
| 1458 |
+
"single_word": false,
|
| 1459 |
+
"special": true
|
| 1460 |
+
},
|
| 1461 |
+
"157073": {
|
| 1462 |
+
"content": "<|reserved_token_178|>",
|
| 1463 |
+
"lstrip": false,
|
| 1464 |
+
"normalized": false,
|
| 1465 |
+
"rstrip": false,
|
| 1466 |
+
"single_word": false,
|
| 1467 |
+
"special": true
|
| 1468 |
+
},
|
| 1469 |
+
"157074": {
|
| 1470 |
+
"content": "<|reserved_token_179|>",
|
| 1471 |
+
"lstrip": false,
|
| 1472 |
+
"normalized": false,
|
| 1473 |
+
"rstrip": false,
|
| 1474 |
+
"single_word": false,
|
| 1475 |
+
"special": true
|
| 1476 |
+
},
|
| 1477 |
+
"157075": {
|
| 1478 |
+
"content": "<|reserved_token_180|>",
|
| 1479 |
+
"lstrip": false,
|
| 1480 |
+
"normalized": false,
|
| 1481 |
+
"rstrip": false,
|
| 1482 |
+
"single_word": false,
|
| 1483 |
+
"special": true
|
| 1484 |
+
},
|
| 1485 |
+
"157076": {
|
| 1486 |
+
"content": "<|reserved_token_181|>",
|
| 1487 |
+
"lstrip": false,
|
| 1488 |
+
"normalized": false,
|
| 1489 |
+
"rstrip": false,
|
| 1490 |
+
"single_word": false,
|
| 1491 |
+
"special": true
|
| 1492 |
+
},
|
| 1493 |
+
"157077": {
|
| 1494 |
+
"content": "<|reserved_token_182|>",
|
| 1495 |
+
"lstrip": false,
|
| 1496 |
+
"normalized": false,
|
| 1497 |
+
"rstrip": false,
|
| 1498 |
+
"single_word": false,
|
| 1499 |
+
"special": true
|
| 1500 |
+
},
|
| 1501 |
+
"157078": {
|
| 1502 |
+
"content": "<|reserved_token_183|>",
|
| 1503 |
+
"lstrip": false,
|
| 1504 |
+
"normalized": false,
|
| 1505 |
+
"rstrip": false,
|
| 1506 |
+
"single_word": false,
|
| 1507 |
+
"special": true
|
| 1508 |
+
},
|
| 1509 |
+
"157079": {
|
| 1510 |
+
"content": "<|reserved_token_184|>",
|
| 1511 |
+
"lstrip": false,
|
| 1512 |
+
"normalized": false,
|
| 1513 |
+
"rstrip": false,
|
| 1514 |
+
"single_word": false,
|
| 1515 |
+
"special": true
|
| 1516 |
+
},
|
| 1517 |
+
"157080": {
|
| 1518 |
+
"content": "<|reserved_token_185|>",
|
| 1519 |
+
"lstrip": false,
|
| 1520 |
+
"normalized": false,
|
| 1521 |
+
"rstrip": false,
|
| 1522 |
+
"single_word": false,
|
| 1523 |
+
"special": true
|
| 1524 |
+
},
|
| 1525 |
+
"157081": {
|
| 1526 |
+
"content": "<|reserved_token_186|>",
|
| 1527 |
+
"lstrip": false,
|
| 1528 |
+
"normalized": false,
|
| 1529 |
+
"rstrip": false,
|
| 1530 |
+
"single_word": false,
|
| 1531 |
+
"special": true
|
| 1532 |
+
},
|
| 1533 |
+
"157082": {
|
| 1534 |
+
"content": "<|reserved_token_187|>",
|
| 1535 |
+
"lstrip": false,
|
| 1536 |
+
"normalized": false,
|
| 1537 |
+
"rstrip": false,
|
| 1538 |
+
"single_word": false,
|
| 1539 |
+
"special": true
|
| 1540 |
+
},
|
| 1541 |
+
"157083": {
|
| 1542 |
+
"content": "<|reserved_token_188|>",
|
| 1543 |
+
"lstrip": false,
|
| 1544 |
+
"normalized": false,
|
| 1545 |
+
"rstrip": false,
|
| 1546 |
+
"single_word": false,
|
| 1547 |
+
"special": true
|
| 1548 |
+
},
|
| 1549 |
+
"157084": {
|
| 1550 |
+
"content": "<|reserved_token_189|>",
|
| 1551 |
+
"lstrip": false,
|
| 1552 |
+
"normalized": false,
|
| 1553 |
+
"rstrip": false,
|
| 1554 |
+
"single_word": false,
|
| 1555 |
+
"special": true
|
| 1556 |
+
},
|
| 1557 |
+
"157085": {
|
| 1558 |
+
"content": "<|reserved_token_190|>",
|
| 1559 |
+
"lstrip": false,
|
| 1560 |
+
"normalized": false,
|
| 1561 |
+
"rstrip": false,
|
| 1562 |
+
"single_word": false,
|
| 1563 |
+
"special": true
|
| 1564 |
+
},
|
| 1565 |
+
"157086": {
|
| 1566 |
+
"content": "<|reserved_token_191|>",
|
| 1567 |
+
"lstrip": false,
|
| 1568 |
+
"normalized": false,
|
| 1569 |
+
"rstrip": false,
|
| 1570 |
+
"single_word": false,
|
| 1571 |
+
"special": true
|
| 1572 |
+
},
|
| 1573 |
+
"157087": {
|
| 1574 |
+
"content": "<|reserved_token_192|>",
|
| 1575 |
+
"lstrip": false,
|
| 1576 |
+
"normalized": false,
|
| 1577 |
+
"rstrip": false,
|
| 1578 |
+
"single_word": false,
|
| 1579 |
+
"special": true
|
| 1580 |
+
},
|
| 1581 |
+
"157088": {
|
| 1582 |
+
"content": "<|reserved_token_193|>",
|
| 1583 |
+
"lstrip": false,
|
| 1584 |
+
"normalized": false,
|
| 1585 |
+
"rstrip": false,
|
| 1586 |
+
"single_word": false,
|
| 1587 |
+
"special": true
|
| 1588 |
+
},
|
| 1589 |
+
"157089": {
|
| 1590 |
+
"content": "<|reserved_token_194|>",
|
| 1591 |
+
"lstrip": false,
|
| 1592 |
+
"normalized": false,
|
| 1593 |
+
"rstrip": false,
|
| 1594 |
+
"single_word": false,
|
| 1595 |
+
"special": true
|
| 1596 |
+
},
|
| 1597 |
+
"157090": {
|
| 1598 |
+
"content": "<|reserved_token_195|>",
|
| 1599 |
+
"lstrip": false,
|
| 1600 |
+
"normalized": false,
|
| 1601 |
+
"rstrip": false,
|
| 1602 |
+
"single_word": false,
|
| 1603 |
+
"special": true
|
| 1604 |
+
},
|
| 1605 |
+
"157091": {
|
| 1606 |
+
"content": "<|reserved_token_196|>",
|
| 1607 |
+
"lstrip": false,
|
| 1608 |
+
"normalized": false,
|
| 1609 |
+
"rstrip": false,
|
| 1610 |
+
"single_word": false,
|
| 1611 |
+
"special": true
|
| 1612 |
+
},
|
| 1613 |
+
"157092": {
|
| 1614 |
+
"content": "<|reserved_token_197|>",
|
| 1615 |
+
"lstrip": false,
|
| 1616 |
+
"normalized": false,
|
| 1617 |
+
"rstrip": false,
|
| 1618 |
+
"single_word": false,
|
| 1619 |
+
"special": true
|
| 1620 |
+
},
|
| 1621 |
+
"157093": {
|
| 1622 |
+
"content": "<|reserved_token_198|>",
|
| 1623 |
+
"lstrip": false,
|
| 1624 |
+
"normalized": false,
|
| 1625 |
+
"rstrip": false,
|
| 1626 |
+
"single_word": false,
|
| 1627 |
+
"special": true
|
| 1628 |
+
},
|
| 1629 |
+
"157094": {
|
| 1630 |
+
"content": "<|reserved_token_199|>",
|
| 1631 |
+
"lstrip": false,
|
| 1632 |
+
"normalized": false,
|
| 1633 |
+
"rstrip": false,
|
| 1634 |
+
"single_word": false,
|
| 1635 |
+
"special": true
|
| 1636 |
+
},
|
| 1637 |
+
"157095": {
|
| 1638 |
+
"content": "<|reserved_token_200|>",
|
| 1639 |
+
"lstrip": false,
|
| 1640 |
+
"normalized": false,
|
| 1641 |
+
"rstrip": false,
|
| 1642 |
+
"single_word": false,
|
| 1643 |
+
"special": true
|
| 1644 |
+
},
|
| 1645 |
+
"157096": {
|
| 1646 |
+
"content": "<|reserved_token_201|>",
|
| 1647 |
+
"lstrip": false,
|
| 1648 |
+
"normalized": false,
|
| 1649 |
+
"rstrip": false,
|
| 1650 |
+
"single_word": false,
|
| 1651 |
+
"special": true
|
| 1652 |
+
},
|
| 1653 |
+
"157097": {
|
| 1654 |
+
"content": "<|reserved_token_202|>",
|
| 1655 |
+
"lstrip": false,
|
| 1656 |
+
"normalized": false,
|
| 1657 |
+
"rstrip": false,
|
| 1658 |
+
"single_word": false,
|
| 1659 |
+
"special": true
|
| 1660 |
+
},
|
| 1661 |
+
"157098": {
|
| 1662 |
+
"content": "<|reserved_token_203|>",
|
| 1663 |
+
"lstrip": false,
|
| 1664 |
+
"normalized": false,
|
| 1665 |
+
"rstrip": false,
|
| 1666 |
+
"single_word": false,
|
| 1667 |
+
"special": true
|
| 1668 |
+
},
|
| 1669 |
+
"157099": {
|
| 1670 |
+
"content": "<|reserved_token_204|>",
|
| 1671 |
+
"lstrip": false,
|
| 1672 |
+
"normalized": false,
|
| 1673 |
+
"rstrip": false,
|
| 1674 |
+
"single_word": false,
|
| 1675 |
+
"special": true
|
| 1676 |
+
},
|
| 1677 |
+
"157100": {
|
| 1678 |
+
"content": "<|reserved_token_205|>",
|
| 1679 |
+
"lstrip": false,
|
| 1680 |
+
"normalized": false,
|
| 1681 |
+
"rstrip": false,
|
| 1682 |
+
"single_word": false,
|
| 1683 |
+
"special": true
|
| 1684 |
+
},
|
| 1685 |
+
"157101": {
|
| 1686 |
+
"content": "<|reserved_token_206|>",
|
| 1687 |
+
"lstrip": false,
|
| 1688 |
+
"normalized": false,
|
| 1689 |
+
"rstrip": false,
|
| 1690 |
+
"single_word": false,
|
| 1691 |
+
"special": true
|
| 1692 |
+
},
|
| 1693 |
+
"157102": {
|
| 1694 |
+
"content": "<|reserved_token_207|>",
|
| 1695 |
+
"lstrip": false,
|
| 1696 |
+
"normalized": false,
|
| 1697 |
+
"rstrip": false,
|
| 1698 |
+
"single_word": false,
|
| 1699 |
+
"special": true
|
| 1700 |
+
},
|
| 1701 |
+
"157103": {
|
| 1702 |
+
"content": "<|reserved_token_208|>",
|
| 1703 |
+
"lstrip": false,
|
| 1704 |
+
"normalized": false,
|
| 1705 |
+
"rstrip": false,
|
| 1706 |
+
"single_word": false,
|
| 1707 |
+
"special": true
|
| 1708 |
+
},
|
| 1709 |
+
"157104": {
|
| 1710 |
+
"content": "<|reserved_token_209|>",
|
| 1711 |
+
"lstrip": false,
|
| 1712 |
+
"normalized": false,
|
| 1713 |
+
"rstrip": false,
|
| 1714 |
+
"single_word": false,
|
| 1715 |
+
"special": true
|
| 1716 |
+
},
|
| 1717 |
+
"157105": {
|
| 1718 |
+
"content": "<|reserved_token_210|>",
|
| 1719 |
+
"lstrip": false,
|
| 1720 |
+
"normalized": false,
|
| 1721 |
+
"rstrip": false,
|
| 1722 |
+
"single_word": false,
|
| 1723 |
+
"special": true
|
| 1724 |
+
},
|
| 1725 |
+
"157106": {
|
| 1726 |
+
"content": "<|reserved_token_211|>",
|
| 1727 |
+
"lstrip": false,
|
| 1728 |
+
"normalized": false,
|
| 1729 |
+
"rstrip": false,
|
| 1730 |
+
"single_word": false,
|
| 1731 |
+
"special": true
|
| 1732 |
+
},
|
| 1733 |
+
"157107": {
|
| 1734 |
+
"content": "<|reserved_token_212|>",
|
| 1735 |
+
"lstrip": false,
|
| 1736 |
+
"normalized": false,
|
| 1737 |
+
"rstrip": false,
|
| 1738 |
+
"single_word": false,
|
| 1739 |
+
"special": true
|
| 1740 |
+
},
|
| 1741 |
+
"157108": {
|
| 1742 |
+
"content": "<|reserved_token_213|>",
|
| 1743 |
+
"lstrip": false,
|
| 1744 |
+
"normalized": false,
|
| 1745 |
+
"rstrip": false,
|
| 1746 |
+
"single_word": false,
|
| 1747 |
+
"special": true
|
| 1748 |
+
},
|
| 1749 |
+
"157109": {
|
| 1750 |
+
"content": "<|reserved_token_214|>",
|
| 1751 |
+
"lstrip": false,
|
| 1752 |
+
"normalized": false,
|
| 1753 |
+
"rstrip": false,
|
| 1754 |
+
"single_word": false,
|
| 1755 |
+
"special": true
|
| 1756 |
+
},
|
| 1757 |
+
"157110": {
|
| 1758 |
+
"content": "<|reserved_token_215|>",
|
| 1759 |
+
"lstrip": false,
|
| 1760 |
+
"normalized": false,
|
| 1761 |
+
"rstrip": false,
|
| 1762 |
+
"single_word": false,
|
| 1763 |
+
"special": true
|
| 1764 |
+
},
|
| 1765 |
+
"157111": {
|
| 1766 |
+
"content": "<|reserved_token_216|>",
|
| 1767 |
+
"lstrip": false,
|
| 1768 |
+
"normalized": false,
|
| 1769 |
+
"rstrip": false,
|
| 1770 |
+
"single_word": false,
|
| 1771 |
+
"special": true
|
| 1772 |
+
},
|
| 1773 |
+
"157112": {
|
| 1774 |
+
"content": "<|reserved_token_217|>",
|
| 1775 |
+
"lstrip": false,
|
| 1776 |
+
"normalized": false,
|
| 1777 |
+
"rstrip": false,
|
| 1778 |
+
"single_word": false,
|
| 1779 |
+
"special": true
|
| 1780 |
+
},
|
| 1781 |
+
"157113": {
|
| 1782 |
+
"content": "<|reserved_token_218|>",
|
| 1783 |
+
"lstrip": false,
|
| 1784 |
+
"normalized": false,
|
| 1785 |
+
"rstrip": false,
|
| 1786 |
+
"single_word": false,
|
| 1787 |
+
"special": true
|
| 1788 |
+
},
|
| 1789 |
+
"157114": {
|
| 1790 |
+
"content": "<|reserved_token_219|>",
|
| 1791 |
+
"lstrip": false,
|
| 1792 |
+
"normalized": false,
|
| 1793 |
+
"rstrip": false,
|
| 1794 |
+
"single_word": false,
|
| 1795 |
+
"special": true
|
| 1796 |
+
},
|
| 1797 |
+
"157115": {
|
| 1798 |
+
"content": "<|reserved_token_220|>",
|
| 1799 |
+
"lstrip": false,
|
| 1800 |
+
"normalized": false,
|
| 1801 |
+
"rstrip": false,
|
| 1802 |
+
"single_word": false,
|
| 1803 |
+
"special": true
|
| 1804 |
+
},
|
| 1805 |
+
"157116": {
|
| 1806 |
+
"content": "<|reserved_token_221|>",
|
| 1807 |
+
"lstrip": false,
|
| 1808 |
+
"normalized": false,
|
| 1809 |
+
"rstrip": false,
|
| 1810 |
+
"single_word": false,
|
| 1811 |
+
"special": true
|
| 1812 |
+
},
|
| 1813 |
+
"157117": {
|
| 1814 |
+
"content": "<|reserved_token_222|>",
|
| 1815 |
+
"lstrip": false,
|
| 1816 |
+
"normalized": false,
|
| 1817 |
+
"rstrip": false,
|
| 1818 |
+
"single_word": false,
|
| 1819 |
+
"special": true
|
| 1820 |
+
},
|
| 1821 |
+
"157118": {
|
| 1822 |
+
"content": "<|reserved_token_223|>",
|
| 1823 |
+
"lstrip": false,
|
| 1824 |
+
"normalized": false,
|
| 1825 |
+
"rstrip": false,
|
| 1826 |
+
"single_word": false,
|
| 1827 |
+
"special": true
|
| 1828 |
+
},
|
| 1829 |
+
"157119": {
|
| 1830 |
+
"content": "<|reserved_token_224|>",
|
| 1831 |
+
"lstrip": false,
|
| 1832 |
+
"normalized": false,
|
| 1833 |
+
"rstrip": false,
|
| 1834 |
+
"single_word": false,
|
| 1835 |
+
"special": true
|
| 1836 |
+
},
|
| 1837 |
+
"157120": {
|
| 1838 |
+
"content": "<|reserved_token_225|>",
|
| 1839 |
+
"lstrip": false,
|
| 1840 |
+
"normalized": false,
|
| 1841 |
+
"rstrip": false,
|
| 1842 |
+
"single_word": false,
|
| 1843 |
+
"special": true
|
| 1844 |
+
},
|
| 1845 |
+
"157121": {
|
| 1846 |
+
"content": "<|reserved_token_226|>",
|
| 1847 |
+
"lstrip": false,
|
| 1848 |
+
"normalized": false,
|
| 1849 |
+
"rstrip": false,
|
| 1850 |
+
"single_word": false,
|
| 1851 |
+
"special": true
|
| 1852 |
+
},
|
| 1853 |
+
"157122": {
|
| 1854 |
+
"content": "<|reserved_token_227|>",
|
| 1855 |
+
"lstrip": false,
|
| 1856 |
+
"normalized": false,
|
| 1857 |
+
"rstrip": false,
|
| 1858 |
+
"single_word": false,
|
| 1859 |
+
"special": true
|
| 1860 |
+
},
|
| 1861 |
+
"157123": {
|
| 1862 |
+
"content": "<|reserved_token_228|>",
|
| 1863 |
+
"lstrip": false,
|
| 1864 |
+
"normalized": false,
|
| 1865 |
+
"rstrip": false,
|
| 1866 |
+
"single_word": false,
|
| 1867 |
+
"special": true
|
| 1868 |
+
},
|
| 1869 |
+
"157124": {
|
| 1870 |
+
"content": "<|reserved_token_229|>",
|
| 1871 |
+
"lstrip": false,
|
| 1872 |
+
"normalized": false,
|
| 1873 |
+
"rstrip": false,
|
| 1874 |
+
"single_word": false,
|
| 1875 |
+
"special": true
|
| 1876 |
+
},
|
| 1877 |
+
"157125": {
|
| 1878 |
+
"content": "<|reserved_token_230|>",
|
| 1879 |
+
"lstrip": false,
|
| 1880 |
+
"normalized": false,
|
| 1881 |
+
"rstrip": false,
|
| 1882 |
+
"single_word": false,
|
| 1883 |
+
"special": true
|
| 1884 |
+
},
|
| 1885 |
+
"157126": {
|
| 1886 |
+
"content": "<|reserved_token_231|>",
|
| 1887 |
+
"lstrip": false,
|
| 1888 |
+
"normalized": false,
|
| 1889 |
+
"rstrip": false,
|
| 1890 |
+
"single_word": false,
|
| 1891 |
+
"special": true
|
| 1892 |
+
},
|
| 1893 |
+
"157127": {
|
| 1894 |
+
"content": "<|reserved_token_232|>",
|
| 1895 |
+
"lstrip": false,
|
| 1896 |
+
"normalized": false,
|
| 1897 |
+
"rstrip": false,
|
| 1898 |
+
"single_word": false,
|
| 1899 |
+
"special": true
|
| 1900 |
+
},
|
| 1901 |
+
"157128": {
|
| 1902 |
+
"content": "<|reserved_token_233|>",
|
| 1903 |
+
"lstrip": false,
|
| 1904 |
+
"normalized": false,
|
| 1905 |
+
"rstrip": false,
|
| 1906 |
+
"single_word": false,
|
| 1907 |
+
"special": true
|
| 1908 |
+
},
|
| 1909 |
+
"157129": {
|
| 1910 |
+
"content": "<|reserved_token_234|>",
|
| 1911 |
+
"lstrip": false,
|
| 1912 |
+
"normalized": false,
|
| 1913 |
+
"rstrip": false,
|
| 1914 |
+
"single_word": false,
|
| 1915 |
+
"special": true
|
| 1916 |
+
},
|
| 1917 |
+
"157130": {
|
| 1918 |
+
"content": "<|reserved_token_235|>",
|
| 1919 |
+
"lstrip": false,
|
| 1920 |
+
"normalized": false,
|
| 1921 |
+
"rstrip": false,
|
| 1922 |
+
"single_word": false,
|
| 1923 |
+
"special": true
|
| 1924 |
+
},
|
| 1925 |
+
"157131": {
|
| 1926 |
+
"content": "<|reserved_token_236|>",
|
| 1927 |
+
"lstrip": false,
|
| 1928 |
+
"normalized": false,
|
| 1929 |
+
"rstrip": false,
|
| 1930 |
+
"single_word": false,
|
| 1931 |
+
"special": true
|
| 1932 |
+
},
|
| 1933 |
+
"157132": {
|
| 1934 |
+
"content": "<|reserved_token_237|>",
|
| 1935 |
+
"lstrip": false,
|
| 1936 |
+
"normalized": false,
|
| 1937 |
+
"rstrip": false,
|
| 1938 |
+
"single_word": false,
|
| 1939 |
+
"special": true
|
| 1940 |
+
},
|
| 1941 |
+
"157133": {
|
| 1942 |
+
"content": "<|reserved_token_238|>",
|
| 1943 |
+
"lstrip": false,
|
| 1944 |
+
"normalized": false,
|
| 1945 |
+
"rstrip": false,
|
| 1946 |
+
"single_word": false,
|
| 1947 |
+
"special": true
|
| 1948 |
+
},
|
| 1949 |
+
"157134": {
|
| 1950 |
+
"content": "<|reserved_token_239|>",
|
| 1951 |
+
"lstrip": false,
|
| 1952 |
+
"normalized": false,
|
| 1953 |
+
"rstrip": false,
|
| 1954 |
+
"single_word": false,
|
| 1955 |
+
"special": true
|
| 1956 |
+
},
|
| 1957 |
+
"157135": {
|
| 1958 |
+
"content": "<|reserved_token_240|>",
|
| 1959 |
+
"lstrip": false,
|
| 1960 |
+
"normalized": false,
|
| 1961 |
+
"rstrip": false,
|
| 1962 |
+
"single_word": false,
|
| 1963 |
+
"special": true
|
| 1964 |
+
},
|
| 1965 |
+
"157136": {
|
| 1966 |
+
"content": "<|reserved_token_241|>",
|
| 1967 |
+
"lstrip": false,
|
| 1968 |
+
"normalized": false,
|
| 1969 |
+
"rstrip": false,
|
| 1970 |
+
"single_word": false,
|
| 1971 |
+
"special": true
|
| 1972 |
+
},
|
| 1973 |
+
"157137": {
|
| 1974 |
+
"content": "<|reserved_token_242|>",
|
| 1975 |
+
"lstrip": false,
|
| 1976 |
+
"normalized": false,
|
| 1977 |
+
"rstrip": false,
|
| 1978 |
+
"single_word": false,
|
| 1979 |
+
"special": true
|
| 1980 |
+
},
|
| 1981 |
+
"157138": {
|
| 1982 |
+
"content": "<|reserved_token_243|>",
|
| 1983 |
+
"lstrip": false,
|
| 1984 |
+
"normalized": false,
|
| 1985 |
+
"rstrip": false,
|
| 1986 |
+
"single_word": false,
|
| 1987 |
+
"special": true
|
| 1988 |
+
},
|
| 1989 |
+
"157139": {
|
| 1990 |
+
"content": "<|reserved_token_244|>",
|
| 1991 |
+
"lstrip": false,
|
| 1992 |
+
"normalized": false,
|
| 1993 |
+
"rstrip": false,
|
| 1994 |
+
"single_word": false,
|
| 1995 |
+
"special": true
|
| 1996 |
+
},
|
| 1997 |
+
"157140": {
|
| 1998 |
+
"content": "<|reserved_token_245|>",
|
| 1999 |
+
"lstrip": false,
|
| 2000 |
+
"normalized": false,
|
| 2001 |
+
"rstrip": false,
|
| 2002 |
+
"single_word": false,
|
| 2003 |
+
"special": true
|
| 2004 |
+
},
|
| 2005 |
+
"157141": {
|
| 2006 |
+
"content": "<|reserved_token_246|>",
|
| 2007 |
+
"lstrip": false,
|
| 2008 |
+
"normalized": false,
|
| 2009 |
+
"rstrip": false,
|
| 2010 |
+
"single_word": false,
|
| 2011 |
+
"special": true
|
| 2012 |
+
},
|
| 2013 |
+
"157142": {
|
| 2014 |
+
"content": "<|reserved_token_247|>",
|
| 2015 |
+
"lstrip": false,
|
| 2016 |
+
"normalized": false,
|
| 2017 |
+
"rstrip": false,
|
| 2018 |
+
"single_word": false,
|
| 2019 |
+
"special": true
|
| 2020 |
+
},
|
| 2021 |
+
"157143": {
|
| 2022 |
+
"content": "<|reserved_token_248|>",
|
| 2023 |
+
"lstrip": false,
|
| 2024 |
+
"normalized": false,
|
| 2025 |
+
"rstrip": false,
|
| 2026 |
+
"single_word": false,
|
| 2027 |
+
"special": true
|
| 2028 |
+
},
|
| 2029 |
+
"157144": {
|
| 2030 |
+
"content": "<|reserved_token_249|>",
|
| 2031 |
+
"lstrip": false,
|
| 2032 |
+
"normalized": false,
|
| 2033 |
+
"rstrip": false,
|
| 2034 |
+
"single_word": false,
|
| 2035 |
+
"special": true
|
| 2036 |
+
},
|
| 2037 |
+
"157145": {
|
| 2038 |
+
"content": "<|reserved_token_250|>",
|
| 2039 |
+
"lstrip": false,
|
| 2040 |
+
"normalized": false,
|
| 2041 |
+
"rstrip": false,
|
| 2042 |
+
"single_word": false,
|
| 2043 |
+
"special": true
|
| 2044 |
+
},
|
| 2045 |
+
"157146": {
|
| 2046 |
+
"content": "<|reserved_token_251|>",
|
| 2047 |
+
"lstrip": false,
|
| 2048 |
+
"normalized": false,
|
| 2049 |
+
"rstrip": false,
|
| 2050 |
+
"single_word": false,
|
| 2051 |
+
"special": true
|
| 2052 |
+
},
|
| 2053 |
+
"157147": {
|
| 2054 |
+
"content": "<|reserved_token_252|>",
|
| 2055 |
+
"lstrip": false,
|
| 2056 |
+
"normalized": false,
|
| 2057 |
+
"rstrip": false,
|
| 2058 |
+
"single_word": false,
|
| 2059 |
+
"special": true
|
| 2060 |
+
},
|
| 2061 |
+
"157148": {
|
| 2062 |
+
"content": "<|reserved_token_253|>",
|
| 2063 |
+
"lstrip": false,
|
| 2064 |
+
"normalized": false,
|
| 2065 |
+
"rstrip": false,
|
| 2066 |
+
"single_word": false,
|
| 2067 |
+
"special": true
|
| 2068 |
+
},
|
| 2069 |
+
"157149": {
|
| 2070 |
+
"content": "<|reserved_token_254|>",
|
| 2071 |
+
"lstrip": false,
|
| 2072 |
+
"normalized": false,
|
| 2073 |
+
"rstrip": false,
|
| 2074 |
+
"single_word": false,
|
| 2075 |
+
"special": true
|
| 2076 |
+
},
|
| 2077 |
+
"157150": {
|
| 2078 |
+
"content": "<|reserved_token_255|>",
|
| 2079 |
+
"lstrip": false,
|
| 2080 |
+
"normalized": false,
|
| 2081 |
+
"rstrip": false,
|
| 2082 |
+
"single_word": false,
|
| 2083 |
+
"special": true
|
| 2084 |
+
},
|
| 2085 |
+
"157151": {
|
| 2086 |
+
"content": "<role>",
|
| 2087 |
+
"lstrip": false,
|
| 2088 |
+
"normalized": false,
|
| 2089 |
+
"rstrip": false,
|
| 2090 |
+
"single_word": false,
|
| 2091 |
+
"special": true
|
| 2092 |
+
},
|
| 2093 |
+
"157152": {
|
| 2094 |
+
"content": "</role>",
|
| 2095 |
+
"lstrip": false,
|
| 2096 |
+
"normalized": false,
|
| 2097 |
+
"rstrip": false,
|
| 2098 |
+
"single_word": false,
|
| 2099 |
+
"special": true
|
| 2100 |
+
}
|
| 2101 |
+
},
|
| 2102 |
+
"bos_token": "<|startoftext|>",
|
| 2103 |
+
"clean_up_tokenization_spaces": false,
|
| 2104 |
+
"cls_token": "[CLS]",
|
| 2105 |
+
"eos_token": "<|role_end|>",
|
| 2106 |
+
"fast_tokenizer": true,
|
| 2107 |
+
"gmask_token": "[gMASK]",
|
| 2108 |
+
"merges_file": null,
|
| 2109 |
+
"model_max_length": 1000000000000000019884624838656,
|
| 2110 |
+
"pad_token": "<|endoftext|>",
|
| 2111 |
+
"tokenizer_class": "PreTrainedTokenizerFast",
|
| 2112 |
+
"trust_remote_code": true
|
| 2113 |
+
}
|
vllm_patch/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Local patch: keep the per-layer SwiGLU clamp on the compressed-tensors MXFP4 MoE path
|
| 2 |
+
|
| 3 |
+
Applied on top of `inclusionAI/vllm@ling_3_0` (`e0040c3` "[Model] Add Bailing V3 support").
|
| 4 |
+
|
| 5 |
+
## The problem
|
| 6 |
+
|
| 7 |
+
Ling-3.0-flash declares a per-layer clamped SwiGLU:
|
| 8 |
+
|
| 9 |
+
```json
|
| 10 |
+
"expert_swiglu_limit_list": [0]*35 + [4]*7, // layers 35-41
|
| 11 |
+
"share_expert_swiglu_limit_list": [0]*34 + [5]*6 + [7]*2
|
| 12 |
+
```
|
| 13 |
+
|
| 14 |
+
`bailing_moe_v3.py` reads it correctly (`_get_layer_swiglu_limit`) and passes
|
| 15 |
+
`swiglu_limit=` into `FusedMoEFactory`, which stores it on `RoutedExperts.swiglu_limit`.
|
| 16 |
+
The unquantized path then honours it — `unquantized_fused_moe_method.py` reads
|
| 17 |
+
`getattr(layer, "swiglu_limit", None)`.
|
| 18 |
+
|
| 19 |
+
The compressed-tensors MXFP4 path did not. Three independent gaps, all of which had to
|
| 20 |
+
be closed for the value to reach the kernel:
|
| 21 |
+
|
| 22 |
+
1. `CompressedTensorsW4A4Mxfp4MoEMethod.get_fused_moe_quant_config` never read
|
| 23 |
+
`layer.swiglu_limit`.
|
| 24 |
+
2. `mxfp4_moe_quant_config` (the W4A4 cutlass builder) had no `gemm1_clamp_limit`
|
| 25 |
+
parameter at all, so even a caller that wanted to pass one could not.
|
| 26 |
+
3. `run_cutlass_moe_mxfp4` took no clamp argument and called
|
| 27 |
+
`apply_moe_activation(activation, c2, c1)` bare. For `MoEActivation.SILU` it also
|
| 28 |
+
takes a fused `ops.silu_and_mul_mxfp4_experts_quant` fast path that has no clamp
|
| 29 |
+
variant.
|
| 30 |
+
|
| 31 |
+
Net effect: on an MXFP4 checkpoint, layers 35-41 computed **unclamped** SwiGLU while
|
| 32 |
+
BF16 clamped them. The divergence is large, not marginal — for a gate activation of
|
| 33 |
+
10.0, `silu(10)*2 = 20.0` against `silu(4)*2 = 7.84`.
|
| 34 |
+
|
| 35 |
+
This is not specific to our quantization: any MXFP4 compressed-tensors checkpoint of a
|
| 36 |
+
model with a SwiGLU limit hits it (gpt-oss-style `limit=7.0` models included).
|
| 37 |
+
|
| 38 |
+
## The change
|
| 39 |
+
|
| 40 |
+
| File | Change |
|
| 41 |
+
|---|---|
|
| 42 |
+
| `vllm/model_executor/layers/fused_moe/config.py` | `mxfp4_moe_quant_config` accepts `gemm1_clamp_limit` and forwards it to `FusedMoEQuantConfig.make` (which already supported it). |
|
| 43 |
+
| `.../compressed_tensors_moe/compressed_tensors_moe_w4a4_mxfp4.py` | `get_fused_moe_quant_config` reads `getattr(layer, "swiglu_limit", None)` and passes it down both the cutlass (`gemm1_clamp_limit=`) and Marlin (`swiglu_limit=`) branches. |
|
| 44 |
+
| `vllm/model_executor/layers/fused_moe/experts/cutlass_moe.py` | `run_cutlass_moe_mxfp4` takes `swiglu_limit`; when set, SILU falls out of the fused fast path into `apply_moe_activation(..., clamp_limit=...)`. `CutlassExpertsMxfp4.apply` passes `self.quant_config.gemm1_clamp_limit`. |
|
| 45 |
+
|
| 46 |
+
`c2` and `workspace2` are allocated unconditionally (`workspace2 = (M * topk, N)`), so
|
| 47 |
+
the generic path is safe to take for any activation.
|
| 48 |
+
|
| 49 |
+
Models that declare no limit are unaffected: `swiglu_limit` stays `None`, the quant
|
| 50 |
+
config field stays `None`, and SILU keeps the fused fast path.
|
| 51 |
+
|
| 52 |
+
## Verification
|
| 53 |
+
|
| 54 |
+
```
|
| 55 |
+
mxfp4_moe_quant_config(..., gemm1_clamp_limit=4.0).gemm1_clamp_limit -> 4.0
|
| 56 |
+
mxfp4_moe_quant_config(...) .gemm1_clamp_limit -> None
|
| 57 |
+
get_fused_moe_quant_config(layer.swiglu_limit=4.0).gemm1_clamp_limit -> 4.0
|
| 58 |
+
get_fused_moe_quant_config(layer.swiglu_limit=None).gemm1_clamp_limit -> None
|
| 59 |
+
apply_moe_activation(SILU, x=[10,-10,2,1]) -> [20.0, -0.00045]
|
| 60 |
+
apply_moe_activation(SILU, x=[10,-10,2,1], clamp_limit=4) -> [ 7.844, -0.00045]
|
| 61 |
+
```
|
| 62 |
+
|
| 63 |
+
All four edits are pure Python, so an editable install picks them up with no rebuild.
|
vllm_patch/compressed_tensors_moe_w4a4_mxfp4.py
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
|
| 7 |
+
import vllm.model_executor.layers.fused_moe.modular_kernel as mk
|
| 8 |
+
from vllm.logger import init_logger
|
| 9 |
+
from vllm.model_executor.layers.fused_moe import (
|
| 10 |
+
FusedMoeWeightScaleSupported,
|
| 11 |
+
RoutedExperts,
|
| 12 |
+
SharedExperts,
|
| 13 |
+
)
|
| 14 |
+
from vllm.model_executor.layers.fused_moe.config import (
|
| 15 |
+
FusedMoEQuantConfig,
|
| 16 |
+
mxfp4_moe_quant_config,
|
| 17 |
+
)
|
| 18 |
+
from vllm.model_executor.layers.fused_moe.experts.cutlass_moe import (
|
| 19 |
+
CutlassExpertsMxfp4,
|
| 20 |
+
)
|
| 21 |
+
from vllm.model_executor.layers.fused_moe.experts.marlin_moe import (
|
| 22 |
+
MarlinExperts,
|
| 23 |
+
)
|
| 24 |
+
from vllm.model_executor.layers.fused_moe.experts.xpu_moe import (
|
| 25 |
+
XPUExpertsMxFp4,
|
| 26 |
+
)
|
| 27 |
+
from vllm.model_executor.layers.fused_moe.oracle.mxfp4 import (
|
| 28 |
+
Mxfp4MoeBackend,
|
| 29 |
+
make_mxfp4_moe_kernel,
|
| 30 |
+
make_mxfp4_moe_quant_config,
|
| 31 |
+
)
|
| 32 |
+
from vllm.model_executor.layers.quantization.compressed_tensors.compressed_tensors_moe import ( # noqa E501
|
| 33 |
+
CompressedTensorsMoEMethod,
|
| 34 |
+
)
|
| 35 |
+
from vllm.model_executor.layers.quantization.utils.marlin_utils_fp4 import (
|
| 36 |
+
prepare_moe_fp4_layer_for_marlin,
|
| 37 |
+
)
|
| 38 |
+
from vllm.model_executor.utils import set_weight_attrs
|
| 39 |
+
from vllm.platforms import current_platform
|
| 40 |
+
|
| 41 |
+
logger = init_logger(__name__)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class CompressedTensorsW4A4Mxfp4MoEMethod(CompressedTensorsMoEMethod):
|
| 45 |
+
def __init__(self, moe):
|
| 46 |
+
super().__init__(moe)
|
| 47 |
+
self.group_size = 32
|
| 48 |
+
self.mxfp4_backend = Mxfp4MoeBackend.MARLIN
|
| 49 |
+
# use cutlass if supported, otherwise fallback to marlin for weight-only FP4
|
| 50 |
+
self.use_cutlass_mxfp4 = CutlassExpertsMxfp4._supports_current_device()
|
| 51 |
+
self.experts_cls: type[mk.FusedMoEExperts]
|
| 52 |
+
if self.use_cutlass_mxfp4:
|
| 53 |
+
logger.info_once("Using CutlassExpertsMxfp4 for MXFP4 MoE")
|
| 54 |
+
self.experts_cls = CutlassExpertsMxfp4
|
| 55 |
+
elif current_platform.is_xpu():
|
| 56 |
+
self.mxfp4_backend = Mxfp4MoeBackend.XPU
|
| 57 |
+
self.experts_cls = XPUExpertsMxFp4
|
| 58 |
+
logger.info_once("Using XPUExpertsMxFp4 for MXFP4 MoE on XPU platform")
|
| 59 |
+
else:
|
| 60 |
+
logger.info_once("Using MarlinExperts for MXFP4 MoE")
|
| 61 |
+
self.experts_cls = MarlinExperts
|
| 62 |
+
|
| 63 |
+
def create_weights(
|
| 64 |
+
self,
|
| 65 |
+
layer: torch.nn.Module,
|
| 66 |
+
num_experts: int,
|
| 67 |
+
hidden_size: int,
|
| 68 |
+
intermediate_size_per_partition: int,
|
| 69 |
+
params_dtype: torch.dtype,
|
| 70 |
+
**extra_weight_attrs,
|
| 71 |
+
):
|
| 72 |
+
layer.num_experts = num_experts
|
| 73 |
+
layer.params_dtype = params_dtype
|
| 74 |
+
|
| 75 |
+
w13_weight = torch.nn.Parameter(
|
| 76 |
+
torch.empty(
|
| 77 |
+
num_experts,
|
| 78 |
+
2 * intermediate_size_per_partition,
|
| 79 |
+
# 2 fp4 items are packed in the input dimension
|
| 80 |
+
hidden_size // 2,
|
| 81 |
+
requires_grad=False,
|
| 82 |
+
dtype=torch.uint8,
|
| 83 |
+
),
|
| 84 |
+
requires_grad=False,
|
| 85 |
+
)
|
| 86 |
+
layer.register_parameter("w13_weight_packed", w13_weight)
|
| 87 |
+
set_weight_attrs(w13_weight, extra_weight_attrs)
|
| 88 |
+
|
| 89 |
+
w2_weight = torch.nn.Parameter(
|
| 90 |
+
torch.empty(
|
| 91 |
+
num_experts,
|
| 92 |
+
hidden_size,
|
| 93 |
+
# 2 fp4 items are packed in the input dimension
|
| 94 |
+
intermediate_size_per_partition // 2,
|
| 95 |
+
dtype=torch.uint8,
|
| 96 |
+
),
|
| 97 |
+
requires_grad=False,
|
| 98 |
+
)
|
| 99 |
+
layer.register_parameter("w2_weight_packed", w2_weight)
|
| 100 |
+
set_weight_attrs(w2_weight, extra_weight_attrs)
|
| 101 |
+
|
| 102 |
+
w13_weight_scale = torch.nn.Parameter(
|
| 103 |
+
torch.empty(
|
| 104 |
+
num_experts,
|
| 105 |
+
2 * intermediate_size_per_partition,
|
| 106 |
+
# 2 fp4 items are packed in the input dimension
|
| 107 |
+
hidden_size // self.group_size,
|
| 108 |
+
dtype=torch.uint8,
|
| 109 |
+
),
|
| 110 |
+
requires_grad=False,
|
| 111 |
+
)
|
| 112 |
+
layer.register_parameter("w13_weight_scale", w13_weight_scale)
|
| 113 |
+
extra_weight_attrs.update(
|
| 114 |
+
{"quant_method": FusedMoeWeightScaleSupported.GROUP.value}
|
| 115 |
+
)
|
| 116 |
+
set_weight_attrs(w13_weight_scale, extra_weight_attrs)
|
| 117 |
+
|
| 118 |
+
w2_weight_scale = torch.nn.Parameter(
|
| 119 |
+
torch.empty(
|
| 120 |
+
num_experts,
|
| 121 |
+
hidden_size,
|
| 122 |
+
# 2 fp4 items are packed in the input dimension
|
| 123 |
+
intermediate_size_per_partition // self.group_size,
|
| 124 |
+
dtype=torch.uint8,
|
| 125 |
+
),
|
| 126 |
+
requires_grad=False,
|
| 127 |
+
)
|
| 128 |
+
layer.register_parameter("w2_weight_scale", w2_weight_scale)
|
| 129 |
+
set_weight_attrs(w2_weight_scale, extra_weight_attrs)
|
| 130 |
+
|
| 131 |
+
def get_fused_moe_quant_config(
|
| 132 |
+
self, layer: torch.nn.Module
|
| 133 |
+
) -> FusedMoEQuantConfig | None:
|
| 134 |
+
# A per-layer SwiGLU clamp is part of the model's forward, not of the
|
| 135 |
+
# quantization scheme — it has to survive into the MXFP4 kernels the same
|
| 136 |
+
# way it does for the unquantized path.
|
| 137 |
+
swiglu_limit = getattr(layer, "swiglu_limit", None)
|
| 138 |
+
if self.use_cutlass_mxfp4:
|
| 139 |
+
# W4A4: both weights and activations quantized to MXFP4
|
| 140 |
+
return mxfp4_moe_quant_config(
|
| 141 |
+
w1_scale=layer.w13_weight_scale,
|
| 142 |
+
w2_scale=layer.w2_weight_scale,
|
| 143 |
+
gemm1_clamp_limit=swiglu_limit,
|
| 144 |
+
)
|
| 145 |
+
else:
|
| 146 |
+
# W4A16: weight-only via Marlin
|
| 147 |
+
return make_mxfp4_moe_quant_config(
|
| 148 |
+
mxfp4_backend=self.mxfp4_backend,
|
| 149 |
+
w1_scale=layer.w13_weight_scale,
|
| 150 |
+
w2_scale=layer.w2_weight_scale,
|
| 151 |
+
swiglu_limit=swiglu_limit,
|
| 152 |
+
layer=layer,
|
| 153 |
+
)
|
| 154 |
+
|
| 155 |
+
def process_weights_after_loading(self, layer: RoutedExperts) -> None:
|
| 156 |
+
layer.w13_weight = torch.nn.Parameter(
|
| 157 |
+
layer.w13_weight_packed.data, requires_grad=False
|
| 158 |
+
)
|
| 159 |
+
delattr(layer, "w13_weight_packed")
|
| 160 |
+
|
| 161 |
+
layer.w2_weight = torch.nn.Parameter(
|
| 162 |
+
layer.w2_weight_packed.data, requires_grad=False
|
| 163 |
+
)
|
| 164 |
+
delattr(layer, "w2_weight_packed")
|
| 165 |
+
|
| 166 |
+
if self.use_cutlass_mxfp4:
|
| 167 |
+
# Swizzle weight scales from flat checkpoint layout [E, N, K//32]
|
| 168 |
+
# to CUTLASS tiled layout [E, numMTiles*numKTiles*512].
|
| 169 |
+
from vllm.model_executor.layers.fused_moe.experts.cutlass_moe import (
|
| 170 |
+
swizzle_mxfp4_scales,
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
E = layer.w13_weight_scale.shape[0]
|
| 174 |
+
w13_N = layer.w13_weight_scale.shape[1]
|
| 175 |
+
w13_scale_K = layer.w13_weight_scale.shape[2]
|
| 176 |
+
w13_K = w13_scale_K * 32
|
| 177 |
+
|
| 178 |
+
w2_M = layer.w2_weight_scale.shape[1]
|
| 179 |
+
w2_scale_N = layer.w2_weight_scale.shape[2]
|
| 180 |
+
w2_N = w2_scale_N * 32
|
| 181 |
+
|
| 182 |
+
swizzled_w13 = []
|
| 183 |
+
swizzled_w2 = []
|
| 184 |
+
for e_idx in range(E):
|
| 185 |
+
s13 = layer.w13_weight_scale[e_idx]
|
| 186 |
+
sw13 = swizzle_mxfp4_scales(s13, w13_N, w13_K)
|
| 187 |
+
swizzled_w13.append(sw13.reshape(w13_N, w13_scale_K))
|
| 188 |
+
s2 = layer.w2_weight_scale[e_idx]
|
| 189 |
+
sw2 = swizzle_mxfp4_scales(s2, w2_M, w2_N)
|
| 190 |
+
swizzled_w2.append(sw2.reshape(w2_M, w2_scale_N))
|
| 191 |
+
layer.w13_weight_scale = torch.nn.Parameter(
|
| 192 |
+
torch.stack(swizzled_w13), requires_grad=False
|
| 193 |
+
)
|
| 194 |
+
layer.w2_weight_scale = torch.nn.Parameter(
|
| 195 |
+
torch.stack(swizzled_w2), requires_grad=False
|
| 196 |
+
)
|
| 197 |
+
elif current_platform.is_xpu():
|
| 198 |
+
pass
|
| 199 |
+
else:
|
| 200 |
+
logger.warning_once(
|
| 201 |
+
"Your GPU does not have native support for FP4 computation "
|
| 202 |
+
"but FP4 quantization is being used. Weight-only FP4 "
|
| 203 |
+
"compression will be used leveraging the Marlin kernel. "
|
| 204 |
+
"This may degrade performance for compute-heavy workloads."
|
| 205 |
+
)
|
| 206 |
+
prepare_moe_fp4_layer_for_marlin(layer)
|
| 207 |
+
|
| 208 |
+
self.moe_quant_config = self.get_fused_moe_quant_config(layer)
|
| 209 |
+
if self.moe_quant_config is not None:
|
| 210 |
+
self.moe_kernel = make_mxfp4_moe_kernel(
|
| 211 |
+
moe_quant_config=self.moe_quant_config,
|
| 212 |
+
moe_config=self.moe,
|
| 213 |
+
experts_cls=self.experts_cls,
|
| 214 |
+
mxfp4_backend=self.mxfp4_backend,
|
| 215 |
+
routing_tables=layer._expert_routing_tables(),
|
| 216 |
+
)
|
| 217 |
+
|
| 218 |
+
def apply(
|
| 219 |
+
self,
|
| 220 |
+
layer: RoutedExperts,
|
| 221 |
+
x: torch.Tensor,
|
| 222 |
+
topk_weights: torch.Tensor,
|
| 223 |
+
topk_ids: torch.Tensor,
|
| 224 |
+
shared_experts: SharedExperts | None,
|
| 225 |
+
shared_experts_input: torch.Tensor | None,
|
| 226 |
+
) -> torch.Tensor:
|
| 227 |
+
assert self.moe_kernel is not None
|
| 228 |
+
return self.moe_kernel.apply(
|
| 229 |
+
x,
|
| 230 |
+
layer.w13_weight,
|
| 231 |
+
layer.w2_weight,
|
| 232 |
+
topk_weights,
|
| 233 |
+
topk_ids,
|
| 234 |
+
activation=layer.activation,
|
| 235 |
+
global_num_experts=layer.global_num_experts,
|
| 236 |
+
expert_map=layer.expert_map,
|
| 237 |
+
apply_router_weight_on_input=layer.apply_router_weight_on_input,
|
| 238 |
+
shared_experts=shared_experts,
|
| 239 |
+
shared_experts_input=shared_experts_input,
|
| 240 |
+
)
|
vllm_patch/config.py
ADDED
|
@@ -0,0 +1,1462 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
| 3 |
+
from dataclasses import dataclass
|
| 4 |
+
from enum import IntEnum
|
| 5 |
+
from typing import Union
|
| 6 |
+
|
| 7 |
+
import torch
|
| 8 |
+
|
| 9 |
+
from vllm.config import ParallelConfig, SchedulerConfig
|
| 10 |
+
from vllm.config.kernel import MoEBackend
|
| 11 |
+
from vllm.distributed import get_dp_group, get_pcp_group, get_tensor_model_parallel_rank
|
| 12 |
+
from vllm.logger import init_logger
|
| 13 |
+
from vllm.model_executor.layers.fused_moe.activation import MoEActivation
|
| 14 |
+
from vllm.model_executor.layers.quantization.utils.ocp_mx_utils import (
|
| 15 |
+
OCP_MX_DTYPES,
|
| 16 |
+
OCP_MX_Scheme,
|
| 17 |
+
)
|
| 18 |
+
from vllm.model_executor.layers.quantization.utils.quant_utils import GroupShape
|
| 19 |
+
from vllm.platforms import current_platform
|
| 20 |
+
from vllm.utils.import_utils import has_triton_kernels
|
| 21 |
+
from vllm.utils.math_utils import cdiv
|
| 22 |
+
|
| 23 |
+
logger = init_logger(__name__)
|
| 24 |
+
|
| 25 |
+
if has_triton_kernels():
|
| 26 |
+
try:
|
| 27 |
+
from triton_kernels.matmul_ogs import PrecisionConfig
|
| 28 |
+
except (ImportError, AttributeError) as e:
|
| 29 |
+
logger.error(
|
| 30 |
+
"Failed to import Triton kernels. Please make sure your triton "
|
| 31 |
+
"version is compatible. Error: %s",
|
| 32 |
+
e,
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _get_config_dtype_str(
|
| 37 |
+
dtype: torch.dtype,
|
| 38 |
+
use_fp8_w8a8: bool = False,
|
| 39 |
+
use_fp8_w8a16: bool = False,
|
| 40 |
+
use_int8_w8a16: bool = False,
|
| 41 |
+
use_int4_w4a16: bool = False,
|
| 42 |
+
ocp_mx_scheme: str | None = None,
|
| 43 |
+
) -> str | None:
|
| 44 |
+
"""
|
| 45 |
+
Return a string used to construct the filename that contains the
|
| 46 |
+
tuning info for a particular quantization scheme. See
|
| 47 |
+
try_get_optimal_moe_config in fused_moe.py.
|
| 48 |
+
"""
|
| 49 |
+
if use_fp8_w8a8:
|
| 50 |
+
return "fp8_w8a8"
|
| 51 |
+
elif use_fp8_w8a16:
|
| 52 |
+
return "fp8_w8a16"
|
| 53 |
+
elif use_int8_w8a16:
|
| 54 |
+
return "int8_w8a16"
|
| 55 |
+
elif use_int4_w4a16:
|
| 56 |
+
return "int4_w4a16"
|
| 57 |
+
elif ocp_mx_scheme is not None:
|
| 58 |
+
# The output of this function is passed to `try_get_optimal_moe_config`,
|
| 59 |
+
# and as we only simulate OCP MX execution in fused_moe for now,
|
| 60 |
+
# we will NOT look for `*,dtype=w_mxfp4_a_mxfp4.json` for now.
|
| 61 |
+
return None
|
| 62 |
+
elif dtype == torch.float:
|
| 63 |
+
# avoiding cases where kernel fails when float32 MoE
|
| 64 |
+
# use fp16/bfloat16 configs
|
| 65 |
+
return "float32"
|
| 66 |
+
return None
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def _quant_flags_to_group_shape(
|
| 70 |
+
quant_dtype: torch.dtype | str | None,
|
| 71 |
+
per_act_token_quant: bool,
|
| 72 |
+
per_out_ch_quant: bool,
|
| 73 |
+
block_shape: list[int] | None,
|
| 74 |
+
) -> tuple[GroupShape | None, GroupShape | None]:
|
| 75 |
+
"""
|
| 76 |
+
Convert MoE quantization flags into more generic GroupShapes.
|
| 77 |
+
"""
|
| 78 |
+
a_shape: GroupShape | None
|
| 79 |
+
w_shape: GroupShape | None
|
| 80 |
+
if block_shape is not None:
|
| 81 |
+
assert not per_act_token_quant
|
| 82 |
+
assert not per_out_ch_quant
|
| 83 |
+
# TODO(bnell): this is not quite right for activations since first
|
| 84 |
+
# dim should be 1.
|
| 85 |
+
a_shape = GroupShape(row=block_shape[0], col=block_shape[1])
|
| 86 |
+
w_shape = GroupShape(row=block_shape[0], col=block_shape[1])
|
| 87 |
+
else:
|
| 88 |
+
w_shape = None
|
| 89 |
+
a_shape = None if quant_dtype is None else GroupShape.PER_TENSOR
|
| 90 |
+
|
| 91 |
+
if per_act_token_quant:
|
| 92 |
+
a_shape = GroupShape.PER_TOKEN
|
| 93 |
+
|
| 94 |
+
if per_out_ch_quant:
|
| 95 |
+
w_shape = GroupShape.PER_TOKEN
|
| 96 |
+
|
| 97 |
+
return a_shape, w_shape
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
# The type of method in top-K routing
|
| 101 |
+
# Please keep this in sync with the counterpart defined in https://github.com/flashinfer-ai/flashinfer/blob/main/include/flashinfer/trtllm/fused_moe/runner.h
|
| 102 |
+
class RoutingMethodType(IntEnum):
|
| 103 |
+
# Default: Softmax -> TopK
|
| 104 |
+
Default = (0,)
|
| 105 |
+
# Renormalize: TopK -> Softmax
|
| 106 |
+
Renormalize = (1,)
|
| 107 |
+
# DeepSeekV3: Sigmoid -> RoutingBiasAdd -> Top2 in group -> Top4 groups
|
| 108 |
+
# -> Top8 experts from the Top4 groups
|
| 109 |
+
DeepSeekV3 = (2,)
|
| 110 |
+
# Llama4: Top1 -> Sigmoid
|
| 111 |
+
Llama4 = (3,)
|
| 112 |
+
# RenormalizeNaive: Softmax -> TopK -> Renormalize
|
| 113 |
+
RenormalizeNaive = (4,)
|
| 114 |
+
# TopK: TopK (no softmax)
|
| 115 |
+
TopK = (5,)
|
| 116 |
+
# SigmoidRenorm: Sigmoid -> TopK -> Renormalize (divide by sum of top-K)
|
| 117 |
+
SigmoidRenorm = (6,)
|
| 118 |
+
# MiniMax2: Sigmoid + Bias -> TopK -> ScaledSumNormalize
|
| 119 |
+
# (routeScale=1.0, epsilon=1e-20)
|
| 120 |
+
MiniMax2 = (7,)
|
| 121 |
+
# Sigmoid: Sigmoid -> TopK (no renormalization)
|
| 122 |
+
Sigmoid = (8,)
|
| 123 |
+
# Unspecified
|
| 124 |
+
Unspecified = (9,)
|
| 125 |
+
# other routing types (not passed to FlashInfer kernels)
|
| 126 |
+
# Deepseek V4 -> sqrtsoftplus + Bias + Normalize
|
| 127 |
+
DeepseekV4 = (100,)
|
| 128 |
+
Custom = (101,)
|
| 129 |
+
Simulated = (102,)
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def get_routing_method_type(
|
| 133 |
+
scoring_func: str,
|
| 134 |
+
top_k: int,
|
| 135 |
+
renormalize: bool,
|
| 136 |
+
num_expert_group: int | None,
|
| 137 |
+
has_e_score_bias: bool,
|
| 138 |
+
routed_scaling_factor: float | None = 1.0,
|
| 139 |
+
) -> RoutingMethodType:
|
| 140 |
+
if scoring_func == "sqrtsoftplus":
|
| 141 |
+
# DeepSeek V4 uses sqrtsoftplus routing with optional routing bias
|
| 142 |
+
# and top-k renormalization.
|
| 143 |
+
if renormalize:
|
| 144 |
+
return RoutingMethodType.DeepseekV4
|
| 145 |
+
else:
|
| 146 |
+
return RoutingMethodType.Unspecified
|
| 147 |
+
|
| 148 |
+
if has_e_score_bias:
|
| 149 |
+
if scoring_func == "sigmoid":
|
| 150 |
+
if not renormalize:
|
| 151 |
+
return RoutingMethodType.Unspecified
|
| 152 |
+
if (num_expert_group or 0) > 0:
|
| 153 |
+
return RoutingMethodType.DeepSeekV3
|
| 154 |
+
if routed_scaling_factor in (None, 1.0):
|
| 155 |
+
return RoutingMethodType.MiniMax2
|
| 156 |
+
return RoutingMethodType.Unspecified
|
| 157 |
+
else:
|
| 158 |
+
return RoutingMethodType.Unspecified
|
| 159 |
+
|
| 160 |
+
if scoring_func == "sigmoid":
|
| 161 |
+
if renormalize:
|
| 162 |
+
return RoutingMethodType.SigmoidRenorm
|
| 163 |
+
return RoutingMethodType.Sigmoid
|
| 164 |
+
|
| 165 |
+
if scoring_func == "softmax":
|
| 166 |
+
if renormalize:
|
| 167 |
+
return RoutingMethodType.RenormalizeNaive
|
| 168 |
+
else:
|
| 169 |
+
return RoutingMethodType.Default
|
| 170 |
+
|
| 171 |
+
return RoutingMethodType.Unspecified
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
@dataclass
|
| 175 |
+
class FusedMoEQuantDesc:
|
| 176 |
+
"""
|
| 177 |
+
A quantization descriptor for fused MoE ops. This class can describe
|
| 178 |
+
either activations or weights.
|
| 179 |
+
"""
|
| 180 |
+
|
| 181 |
+
# The quantized type of this parameters. None means unquantized or
|
| 182 |
+
# already quantized.
|
| 183 |
+
# TODO (bnell): use scalar_type instead of Union.
|
| 184 |
+
dtype: torch.dtype | str | None = None
|
| 185 |
+
|
| 186 |
+
# A field that describes the quantization group shape, from quant_utils.py.
|
| 187 |
+
# * (-1, -1) for per-tensor quantization
|
| 188 |
+
# * (1, -1) for per-row quantization
|
| 189 |
+
# * (-1, 1) for per-column quantization
|
| 190 |
+
# * (128, 128) for 128x128 deepseek style block quantization
|
| 191 |
+
# * (1, 128) for deepseek style activation quantization
|
| 192 |
+
# (i.e. per-token-per-group)
|
| 193 |
+
shape: GroupShape | None = None
|
| 194 |
+
|
| 195 |
+
# Quantization scales.
|
| 196 |
+
# TODO(bnell): maybe put PrecisionConfigs in subclass of QuantDesc?
|
| 197 |
+
scale: Union[torch.Tensor, "PrecisionConfig", None] = None
|
| 198 |
+
|
| 199 |
+
# Quantization alphas or gscales, used for nvfp4 types.
|
| 200 |
+
# W4A8 FP8: used for per-channel scales
|
| 201 |
+
# TODO(bnell): put some of these in subclasses
|
| 202 |
+
alpha_or_gscale: torch.Tensor | None = None
|
| 203 |
+
|
| 204 |
+
# Zero points for int4/int8 types
|
| 205 |
+
zp: torch.Tensor | None = None
|
| 206 |
+
|
| 207 |
+
# Biases for GPT triton MoE
|
| 208 |
+
bias: torch.Tensor | None = None
|
| 209 |
+
|
| 210 |
+
|
| 211 |
+
# TODO(bnell): have subclasses for specific moe methods?
|
| 212 |
+
# e.g. for specific arguments bias, precision, etc.
|
| 213 |
+
@dataclass
|
| 214 |
+
class FusedMoEQuantConfig:
|
| 215 |
+
"""
|
| 216 |
+
The FusedMoEQuantConfig contains all the quantization parameters for
|
| 217 |
+
a single FusedMoEMethodBase operation. It consists of four
|
| 218 |
+
FusedMoEQuantDescs, one for each activation and set of weights.
|
| 219 |
+
|
| 220 |
+
Each FusedMoEMethodBase must implement a get_fused_moe_quant_config
|
| 221 |
+
method to construct a FusedMoEQuantConfig for use with that class.
|
| 222 |
+
|
| 223 |
+
FusedMoEQuant configs are only used for modular kernels, fused_experts
|
| 224 |
+
(from fused_moe.py), cutlass_moe_fp[48], rocm_aiter_fused_experts and
|
| 225 |
+
triton_kernel_moe_forward. Other MoE methods can ignore the
|
| 226 |
+
FusedMoEQuantConfig (for now) and hardcode it to None.
|
| 227 |
+
|
| 228 |
+
There are currently some restrictions on what can be expressed:
|
| 229 |
+
- Most MoE ops only support similar quantization strategies for
|
| 230 |
+
each parameter, e.g. both weights must have the same GroupShape
|
| 231 |
+
and both activations must share the same GroupShape. One exception to
|
| 232 |
+
this is the cutlass moe which allows per channel quantization on the
|
| 233 |
+
outputs. Note: this restrictions are not always rigorously checked.
|
| 234 |
+
- Not all fused MoE functions support all the parameters, e.g. zero points,
|
| 235 |
+
global scales, alphas and biases are not universally supported.
|
| 236 |
+
- Fully general GroupShapes are not allowed. Activations only support
|
| 237 |
+
per token, per tensor or K-blocked.
|
| 238 |
+
- Weights are not required to have a GroupShape since they have already
|
| 239 |
+
been quantized.
|
| 240 |
+
|
| 241 |
+
Other notes:
|
| 242 |
+
- PrecisionConfigs are specific to GPT OSS Triton.
|
| 243 |
+
- As a follow up it would probably make sense to subclass FusedMoEQuantDesc
|
| 244 |
+
or FusedMoEQuantConfig for particular FusedMoEMethodBase subclasses
|
| 245 |
+
so that only the required quantization parameters are used/stored.
|
| 246 |
+
"""
|
| 247 |
+
|
| 248 |
+
# TODO(bnell) make sure a1_scales/a2_scales don't interfere with chunking
|
| 249 |
+
_a1: FusedMoEQuantDesc
|
| 250 |
+
_a2: FusedMoEQuantDesc
|
| 251 |
+
_w1: FusedMoEQuantDesc
|
| 252 |
+
_w2: FusedMoEQuantDesc
|
| 253 |
+
is_scale_swizzled: bool = True
|
| 254 |
+
|
| 255 |
+
# MXFP4-specific TRTLLM parameters for SwiGLU activation clamping.
|
| 256 |
+
# These correspond to gemm1_alpha, gemm1_beta, gemm1_clamp_limit
|
| 257 |
+
# in TrtLlmMxfp4ExpertsBase.
|
| 258 |
+
gemm1_alpha: float | None = None
|
| 259 |
+
gemm1_beta: float | None = None
|
| 260 |
+
gemm1_clamp_limit: float | None = None
|
| 261 |
+
|
| 262 |
+
mx_alignment: int = 0
|
| 263 |
+
|
| 264 |
+
def __post_init__(self):
|
| 265 |
+
assert not self.per_act_token_quant or self.block_shape is None, (
|
| 266 |
+
"illegal quantization"
|
| 267 |
+
)
|
| 268 |
+
|
| 269 |
+
#
|
| 270 |
+
# Convenience accessors for various properties.
|
| 271 |
+
#
|
| 272 |
+
|
| 273 |
+
@property
|
| 274 |
+
def quant_dtype(self) -> torch.dtype | str | None:
|
| 275 |
+
return self._a1.dtype
|
| 276 |
+
|
| 277 |
+
@property
|
| 278 |
+
def weight_quant_dtype(self) -> torch.dtype | str | None:
|
| 279 |
+
return self._w1.dtype
|
| 280 |
+
|
| 281 |
+
@property
|
| 282 |
+
def is_quantized(self) -> bool:
|
| 283 |
+
return self.quant_dtype is not None
|
| 284 |
+
|
| 285 |
+
@property
|
| 286 |
+
def is_per_act_token(self) -> bool:
|
| 287 |
+
return self._a1.shape == GroupShape.PER_TOKEN
|
| 288 |
+
|
| 289 |
+
@property
|
| 290 |
+
def per_act_token_quant(self) -> bool:
|
| 291 |
+
return self._a1.shape == GroupShape.PER_TOKEN
|
| 292 |
+
|
| 293 |
+
@property
|
| 294 |
+
def per_out_ch_quant(self) -> bool:
|
| 295 |
+
return self._w1.shape == GroupShape.PER_TOKEN
|
| 296 |
+
|
| 297 |
+
@property
|
| 298 |
+
def is_per_tensor(self) -> bool:
|
| 299 |
+
return self._a1.shape == GroupShape.PER_TENSOR
|
| 300 |
+
|
| 301 |
+
@property
|
| 302 |
+
def block_shape(self) -> list[int] | None:
|
| 303 |
+
if (
|
| 304 |
+
self._a1.shape is not None
|
| 305 |
+
and self._a1.shape != GroupShape.PER_TENSOR
|
| 306 |
+
and self._a1.shape != GroupShape.PER_TOKEN
|
| 307 |
+
):
|
| 308 |
+
return [self._a1.shape.row, self._a1.shape.col]
|
| 309 |
+
else:
|
| 310 |
+
return None
|
| 311 |
+
|
| 312 |
+
@property
|
| 313 |
+
def is_block_quantized(self) -> bool:
|
| 314 |
+
return self.block_shape is not None
|
| 315 |
+
|
| 316 |
+
@property
|
| 317 |
+
def a1_scale(self) -> torch.Tensor | None:
|
| 318 |
+
assert self._a1.scale is None or isinstance(self._a1.scale, torch.Tensor)
|
| 319 |
+
return self._a1.scale
|
| 320 |
+
|
| 321 |
+
@property
|
| 322 |
+
def a1_gscale(self) -> torch.Tensor | None:
|
| 323 |
+
return self._a1.alpha_or_gscale
|
| 324 |
+
|
| 325 |
+
@property
|
| 326 |
+
def a2_scale(self) -> torch.Tensor | None:
|
| 327 |
+
assert self._a2.scale is None or isinstance(self._a2.scale, torch.Tensor)
|
| 328 |
+
return self._a2.scale
|
| 329 |
+
|
| 330 |
+
@property
|
| 331 |
+
def a2_gscale(self) -> torch.Tensor | None:
|
| 332 |
+
return self._a2.alpha_or_gscale
|
| 333 |
+
|
| 334 |
+
@property
|
| 335 |
+
def w1_scale(self) -> torch.Tensor | None:
|
| 336 |
+
assert self._w1.scale is None or isinstance(self._w1.scale, torch.Tensor)
|
| 337 |
+
return self._w1.scale
|
| 338 |
+
|
| 339 |
+
@property
|
| 340 |
+
def w1_zp(self) -> torch.Tensor | None:
|
| 341 |
+
return self._w1.zp
|
| 342 |
+
|
| 343 |
+
@property
|
| 344 |
+
def w1_bias(self) -> torch.Tensor | None:
|
| 345 |
+
return self._w1.bias
|
| 346 |
+
|
| 347 |
+
@property
|
| 348 |
+
def w1_precision(self) -> "PrecisionConfig | None":
|
| 349 |
+
assert self._w1.scale is None or isinstance(self._w1.scale, PrecisionConfig)
|
| 350 |
+
return self._w1.scale
|
| 351 |
+
|
| 352 |
+
@property
|
| 353 |
+
def g1_alphas(self) -> torch.Tensor | None:
|
| 354 |
+
return self._w1.alpha_or_gscale
|
| 355 |
+
|
| 356 |
+
@property
|
| 357 |
+
def w2_scale(self) -> torch.Tensor | None:
|
| 358 |
+
assert self._w2.scale is None or isinstance(self._w2.scale, torch.Tensor)
|
| 359 |
+
return self._w2.scale
|
| 360 |
+
|
| 361 |
+
@property
|
| 362 |
+
def w2_zp(self) -> torch.Tensor | None:
|
| 363 |
+
return self._w2.zp
|
| 364 |
+
|
| 365 |
+
@property
|
| 366 |
+
def w2_bias(self) -> torch.Tensor | None:
|
| 367 |
+
return self._w2.bias
|
| 368 |
+
|
| 369 |
+
@property
|
| 370 |
+
def w2_precision(self) -> "PrecisionConfig | None":
|
| 371 |
+
assert self._w2.scale is None or isinstance(self._w2.scale, PrecisionConfig)
|
| 372 |
+
return self._w2.scale
|
| 373 |
+
|
| 374 |
+
@property
|
| 375 |
+
def g2_alphas(self) -> torch.Tensor | None:
|
| 376 |
+
return self._w2.alpha_or_gscale
|
| 377 |
+
|
| 378 |
+
@property
|
| 379 |
+
def use_fp8_w8a8(self) -> bool:
|
| 380 |
+
return self.quant_dtype == current_platform.fp8_dtype()
|
| 381 |
+
|
| 382 |
+
@property
|
| 383 |
+
def use_int8_w8a8(self) -> bool:
|
| 384 |
+
return self.quant_dtype == torch.int8
|
| 385 |
+
|
| 386 |
+
@property
|
| 387 |
+
def use_int8_w8a16(self) -> bool:
|
| 388 |
+
return self._a1.dtype is None and self._w1.dtype == torch.int8
|
| 389 |
+
|
| 390 |
+
@property
|
| 391 |
+
def use_fp8_w8a16(self) -> bool:
|
| 392 |
+
return self._a1.dtype is None and self._w1.dtype == current_platform.fp8_dtype()
|
| 393 |
+
|
| 394 |
+
@property
|
| 395 |
+
def use_int4_w4a16(self) -> bool:
|
| 396 |
+
return self._a1.dtype is None and self._w1.dtype == "int4"
|
| 397 |
+
|
| 398 |
+
@property
|
| 399 |
+
def use_nvfp4_w4a16(self) -> bool:
|
| 400 |
+
return self._a1.dtype is None and self._w1.dtype == "nvfp4"
|
| 401 |
+
|
| 402 |
+
@property
|
| 403 |
+
def ocp_mx_scheme(self) -> str | None:
|
| 404 |
+
if not hasattr(self, "_ocp_mx_scheme"):
|
| 405 |
+
if (self._a1.dtype is not None and not isinstance(self._a1.dtype, str)) or (
|
| 406 |
+
self._w1.dtype is not None and not isinstance(self._w1.dtype, str)
|
| 407 |
+
):
|
| 408 |
+
self._ocp_mx_scheme = None
|
| 409 |
+
else:
|
| 410 |
+
ocp_mx_scheme = OCP_MX_Scheme.from_quant_dtype(
|
| 411 |
+
self._a1.dtype, self._w1.dtype
|
| 412 |
+
)
|
| 413 |
+
|
| 414 |
+
if ocp_mx_scheme is not None:
|
| 415 |
+
ocp_mx_scheme = ocp_mx_scheme.value
|
| 416 |
+
|
| 417 |
+
self._ocp_mx_scheme = ocp_mx_scheme
|
| 418 |
+
|
| 419 |
+
return self._ocp_mx_scheme
|
| 420 |
+
|
| 421 |
+
@property
|
| 422 |
+
def use_mxfp4_w4a16(self) -> bool:
|
| 423 |
+
return self._a1.dtype is None and self._w1.dtype == "mxfp4"
|
| 424 |
+
|
| 425 |
+
@property
|
| 426 |
+
def use_mxfp4_w4a4(self) -> bool:
|
| 427 |
+
return self._a1.dtype == "mxfp4" and self._w1.dtype == "mxfp4"
|
| 428 |
+
|
| 429 |
+
@property
|
| 430 |
+
def use_nvfp4_w4a4(self) -> bool:
|
| 431 |
+
return self.quant_dtype == "nvfp4"
|
| 432 |
+
|
| 433 |
+
@property
|
| 434 |
+
def use_mxfp4_w4a8(self) -> bool:
|
| 435 |
+
return self._a1.dtype == "fp8" and self._w1.dtype == "mxfp4"
|
| 436 |
+
|
| 437 |
+
def config_name(self, dtype: torch.dtype) -> str | None:
|
| 438 |
+
"""
|
| 439 |
+
Return a string used to construct the filename that contains the
|
| 440 |
+
tuning info for a particular quantization scheme. See
|
| 441 |
+
try_get_optimal_moe_config in fused_moe.py.
|
| 442 |
+
"""
|
| 443 |
+
return _get_config_dtype_str(
|
| 444 |
+
use_fp8_w8a8=self.use_fp8_w8a8,
|
| 445 |
+
use_fp8_w8a16=self.use_fp8_w8a16,
|
| 446 |
+
use_int8_w8a16=self.use_int8_w8a16,
|
| 447 |
+
use_int4_w4a16=self.use_int4_w4a16,
|
| 448 |
+
ocp_mx_scheme=self.ocp_mx_scheme,
|
| 449 |
+
dtype=dtype,
|
| 450 |
+
)
|
| 451 |
+
|
| 452 |
+
def scale_shape(
|
| 453 |
+
self,
|
| 454 |
+
max_tokens: int,
|
| 455 |
+
hidden_dim: int,
|
| 456 |
+
) -> tuple[int, int] | None:
|
| 457 |
+
"""
|
| 458 |
+
Construct the proper activation scale shape for this
|
| 459 |
+
config.
|
| 460 |
+
"""
|
| 461 |
+
if self.is_quantized:
|
| 462 |
+
if self.is_block_quantized:
|
| 463 |
+
assert self.block_shape is not None
|
| 464 |
+
_, block_k = self.block_shape
|
| 465 |
+
k_tiles = cdiv(hidden_dim, block_k)
|
| 466 |
+
return (max_tokens, k_tiles)
|
| 467 |
+
elif self.is_per_act_token:
|
| 468 |
+
return (max_tokens, 1)
|
| 469 |
+
else:
|
| 470 |
+
return (1, 1)
|
| 471 |
+
else:
|
| 472 |
+
return None
|
| 473 |
+
|
| 474 |
+
def batched_scale_shape(
|
| 475 |
+
self,
|
| 476 |
+
num_experts: int,
|
| 477 |
+
max_tokens: int,
|
| 478 |
+
hidden_dim: int,
|
| 479 |
+
) -> tuple[int, int, int] | None:
|
| 480 |
+
"""
|
| 481 |
+
Construct the proper activation batched scale shape for this
|
| 482 |
+
config, e.g. (num experts, *scale_shape).
|
| 483 |
+
"""
|
| 484 |
+
if self.is_quantized:
|
| 485 |
+
scale_shape = self.scale_shape(max_tokens, hidden_dim)
|
| 486 |
+
assert scale_shape is not None
|
| 487 |
+
return (num_experts, *scale_shape)
|
| 488 |
+
else:
|
| 489 |
+
return None
|
| 490 |
+
|
| 491 |
+
@staticmethod
|
| 492 |
+
def make(
|
| 493 |
+
quant_dtype: torch.dtype | str | None = None,
|
| 494 |
+
per_act_token_quant: bool = False,
|
| 495 |
+
per_out_ch_quant: bool = False,
|
| 496 |
+
block_shape: list[int] | None = None,
|
| 497 |
+
w1_scale: Union[torch.Tensor, "PrecisionConfig", None] = None,
|
| 498 |
+
w2_scale: Union[torch.Tensor, "PrecisionConfig", None] = None,
|
| 499 |
+
a1_scale: torch.Tensor | None = None,
|
| 500 |
+
a2_scale: torch.Tensor | None = None,
|
| 501 |
+
g1_alphas: torch.Tensor | None = None,
|
| 502 |
+
g2_alphas: torch.Tensor | None = None,
|
| 503 |
+
a1_gscale: torch.Tensor | None = None,
|
| 504 |
+
a2_gscale: torch.Tensor | None = None,
|
| 505 |
+
w1_bias: torch.Tensor | None = None,
|
| 506 |
+
w2_bias: torch.Tensor | None = None,
|
| 507 |
+
w1_zp: torch.Tensor | None = None,
|
| 508 |
+
w2_zp: torch.Tensor | None = None,
|
| 509 |
+
weight_dtype: torch.dtype | str | None = None,
|
| 510 |
+
is_scale_swizzled: bool = True,
|
| 511 |
+
gemm1_alpha: float | None = None,
|
| 512 |
+
gemm1_beta: float | None = None,
|
| 513 |
+
gemm1_clamp_limit: float | None = None,
|
| 514 |
+
) -> "FusedMoEQuantConfig":
|
| 515 |
+
"""
|
| 516 |
+
General builder function for a FusedMoEQuantConfig.
|
| 517 |
+
- quant_dtype: Optional quantization type. None if activations are
|
| 518 |
+
unquantized or quantized prior to calling. Note: "nvfp4", "mxfp4",
|
| 519 |
+
"mxfp6_e3m2", "mxfp6_e2m3" are the only valid string values
|
| 520 |
+
for quant_dtype.
|
| 521 |
+
- per_act_token_quant: Activations have per token quantization.
|
| 522 |
+
- per_out_ch_quant: Outputs have per channel quantization. (only
|
| 523 |
+
for cutlass).
|
| 524 |
+
- block_shape: Optional block size for block-wise quantization.
|
| 525 |
+
Incompatible with per_act_token and per_out_ch quant.
|
| 526 |
+
- w1_scale: Optional scale to be used for w1.
|
| 527 |
+
- w2_scale: Optional scale to be used for w2.
|
| 528 |
+
- a1_scale: Optional scale to be used for a1.
|
| 529 |
+
- a2_scale: Optional scale to be used for a2.
|
| 530 |
+
- g1_alphas: Optional global quantization scales for w1 (for nvfp4).
|
| 531 |
+
Optional per-channel scales for w1 (for W4A8 FP8).
|
| 532 |
+
Optional dq scale i.e. w_scale * a_scale (for W8A8 fp8).
|
| 533 |
+
- g2_alphas: Optional global quantization scales for w2 (for nvfp4).
|
| 534 |
+
Optional per-channel scales for w2 (for W4A8 FP8).
|
| 535 |
+
Optional dq scale i.e. w_scale * a_scale (for W8A8 fp8).
|
| 536 |
+
- a1_gscale: Optional global quantization scales for a1 (1.0 /a2_scale).
|
| 537 |
+
- a2_gscale: Optional global quantization scales for a2 (1.0 /a2_scale).
|
| 538 |
+
|
| 539 |
+
- w1_bias: Optional biases for w1 (GPT OSS Triton).
|
| 540 |
+
- w2_bias: Optional biases for w1 (GPT OSS Triton).
|
| 541 |
+
- w1_zp: Optional w1 zero points for int4/int8 quantization.
|
| 542 |
+
- w2_zp: Optional w2 zero points for int4/int8 quantization.
|
| 543 |
+
- is_scale_swizzled: Whether the activation scale-factor layout is
|
| 544 |
+
swizzled. Pass through to the underlying quantization kernel for
|
| 545 |
+
dtypes that distinguish layouts (nvfp4, mxfp8). Defaults to True.
|
| 546 |
+
- gemm1_alpha: Optional MXFP4 TRTLLM SwiGLU alpha parameter.
|
| 547 |
+
- gemm1_beta: Optional MXFP4 TRTLLM SwiGLU beta parameter.
|
| 548 |
+
- gemm1_clamp_limit: Optional MXFP4 TRTLLM SwiGLU clamp limit.
|
| 549 |
+
"""
|
| 550 |
+
assert not isinstance(quant_dtype, str) or quant_dtype in {
|
| 551 |
+
"nvfp4",
|
| 552 |
+
"mxfp4",
|
| 553 |
+
"mxfp6_e3m2",
|
| 554 |
+
"mxfp6_e2m3",
|
| 555 |
+
"mxfp8",
|
| 556 |
+
}
|
| 557 |
+
assert not isinstance(weight_dtype, str) or weight_dtype in {
|
| 558 |
+
"nvfp4",
|
| 559 |
+
"mxfp4",
|
| 560 |
+
"mxfp6_e3m2",
|
| 561 |
+
"mxfp6_e2m3",
|
| 562 |
+
"int4",
|
| 563 |
+
"mxfp8",
|
| 564 |
+
}
|
| 565 |
+
|
| 566 |
+
if weight_dtype is None:
|
| 567 |
+
weight_dtype = quant_dtype
|
| 568 |
+
|
| 569 |
+
a_shape, w_shape = _quant_flags_to_group_shape(
|
| 570 |
+
quant_dtype, per_act_token_quant, per_out_ch_quant, block_shape
|
| 571 |
+
)
|
| 572 |
+
quant_config = FusedMoEQuantConfig(
|
| 573 |
+
_a1=FusedMoEQuantDesc(quant_dtype, a_shape, a1_scale, a1_gscale),
|
| 574 |
+
_a2=FusedMoEQuantDesc(quant_dtype, a_shape, a2_scale, a2_gscale),
|
| 575 |
+
_w1=FusedMoEQuantDesc(
|
| 576 |
+
weight_dtype, w_shape, w1_scale, g1_alphas, w1_zp, w1_bias
|
| 577 |
+
),
|
| 578 |
+
_w2=FusedMoEQuantDesc(
|
| 579 |
+
weight_dtype, w_shape, w2_scale, g2_alphas, w2_zp, w2_bias
|
| 580 |
+
),
|
| 581 |
+
is_scale_swizzled=is_scale_swizzled,
|
| 582 |
+
gemm1_alpha=gemm1_alpha,
|
| 583 |
+
gemm1_beta=gemm1_beta,
|
| 584 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 585 |
+
)
|
| 586 |
+
assert quant_config.per_act_token_quant == per_act_token_quant
|
| 587 |
+
assert quant_config.per_out_ch_quant == per_out_ch_quant
|
| 588 |
+
assert quant_config.block_shape == block_shape
|
| 589 |
+
return quant_config
|
| 590 |
+
|
| 591 |
+
|
| 592 |
+
def fp8_w8a8_moe_quant_config(
|
| 593 |
+
w1_scale: torch.Tensor,
|
| 594 |
+
w2_scale: torch.Tensor,
|
| 595 |
+
a1_scale: torch.Tensor | None = None,
|
| 596 |
+
a2_scale: torch.Tensor | None = None,
|
| 597 |
+
w1_bias: torch.Tensor | None = None,
|
| 598 |
+
w2_bias: torch.Tensor | None = None,
|
| 599 |
+
per_act_token_quant: bool = False,
|
| 600 |
+
per_out_ch_quant: bool = False,
|
| 601 |
+
block_shape: list[int] | None = None,
|
| 602 |
+
a1_gscale: torch.Tensor | None = None,
|
| 603 |
+
a2_gscale: torch.Tensor | None = None,
|
| 604 |
+
g1_alphas: torch.Tensor | None = None,
|
| 605 |
+
g2_alphas: torch.Tensor | None = None,
|
| 606 |
+
gemm1_alpha: float | None = None,
|
| 607 |
+
gemm1_beta: float | None = None,
|
| 608 |
+
gemm1_clamp_limit: float | None = None,
|
| 609 |
+
) -> FusedMoEQuantConfig:
|
| 610 |
+
"""
|
| 611 |
+
Construct a quant config for fp8 activations and fp8 weights.
|
| 612 |
+
"""
|
| 613 |
+
return FusedMoEQuantConfig.make(
|
| 614 |
+
current_platform.fp8_dtype(),
|
| 615 |
+
w1_scale=w1_scale,
|
| 616 |
+
g1_alphas=g1_alphas,
|
| 617 |
+
w2_scale=w2_scale,
|
| 618 |
+
g2_alphas=g2_alphas,
|
| 619 |
+
w1_bias=w1_bias,
|
| 620 |
+
w2_bias=w2_bias,
|
| 621 |
+
a1_scale=a1_scale,
|
| 622 |
+
a1_gscale=a1_gscale,
|
| 623 |
+
a2_scale=a2_scale,
|
| 624 |
+
a2_gscale=a2_gscale,
|
| 625 |
+
per_act_token_quant=per_act_token_quant,
|
| 626 |
+
per_out_ch_quant=per_out_ch_quant,
|
| 627 |
+
block_shape=block_shape,
|
| 628 |
+
gemm1_alpha=gemm1_alpha,
|
| 629 |
+
gemm1_beta=gemm1_beta,
|
| 630 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 631 |
+
)
|
| 632 |
+
|
| 633 |
+
|
| 634 |
+
def int8_w8a8_moe_quant_config(
|
| 635 |
+
w1_scale: torch.Tensor,
|
| 636 |
+
w2_scale: torch.Tensor,
|
| 637 |
+
a1_scale: torch.Tensor | None,
|
| 638 |
+
a2_scale: torch.Tensor | None,
|
| 639 |
+
w1_bias: torch.Tensor | None = None,
|
| 640 |
+
w2_bias: torch.Tensor | None = None,
|
| 641 |
+
per_act_token_quant: bool = False,
|
| 642 |
+
) -> FusedMoEQuantConfig:
|
| 643 |
+
"""
|
| 644 |
+
Construct a quant config for int8 activations and int8 weights.
|
| 645 |
+
"""
|
| 646 |
+
return FusedMoEQuantConfig.make(
|
| 647 |
+
torch.int8,
|
| 648 |
+
w1_scale=w1_scale,
|
| 649 |
+
w2_scale=w2_scale,
|
| 650 |
+
a1_scale=a1_scale,
|
| 651 |
+
a2_scale=a2_scale,
|
| 652 |
+
w1_bias=w1_bias,
|
| 653 |
+
w2_bias=w2_bias,
|
| 654 |
+
per_act_token_quant=per_act_token_quant,
|
| 655 |
+
per_out_ch_quant=False,
|
| 656 |
+
block_shape=None,
|
| 657 |
+
)
|
| 658 |
+
|
| 659 |
+
|
| 660 |
+
def gptq_marlin_moe_quant_config(
|
| 661 |
+
w1_scale: torch.Tensor,
|
| 662 |
+
w2_scale: torch.Tensor,
|
| 663 |
+
weight_bits: int,
|
| 664 |
+
group_size: int,
|
| 665 |
+
w1_zp: torch.Tensor | None = None,
|
| 666 |
+
w2_zp: torch.Tensor | None = None,
|
| 667 |
+
w1_bias: torch.Tensor | None = None,
|
| 668 |
+
w2_bias: torch.Tensor | None = None,
|
| 669 |
+
):
|
| 670 |
+
"""
|
| 671 |
+
Construct a quant config for gptq marlin quantization.
|
| 672 |
+
"""
|
| 673 |
+
from vllm.model_executor.layers.quantization.utils.quant_utils import GroupShape
|
| 674 |
+
|
| 675 |
+
w_shape = None if group_size == -1 else GroupShape(row=1, col=group_size)
|
| 676 |
+
|
| 677 |
+
# Activations are NOT quantized for GPTQ (fp16/bf16)
|
| 678 |
+
a_shape = w_shape # Same as weight shape for alignment
|
| 679 |
+
|
| 680 |
+
# Determine weight dtype
|
| 681 |
+
if weight_bits == 4:
|
| 682 |
+
weight_dtype = "int4"
|
| 683 |
+
elif weight_bits == 8:
|
| 684 |
+
weight_dtype = torch.int8
|
| 685 |
+
else:
|
| 686 |
+
raise ValueError(f"Unsupported weight_bits: {weight_bits}")
|
| 687 |
+
|
| 688 |
+
return FusedMoEQuantConfig(
|
| 689 |
+
_a1=FusedMoEQuantDesc(dtype=None, shape=a_shape),
|
| 690 |
+
_a2=FusedMoEQuantDesc(dtype=None, shape=a_shape),
|
| 691 |
+
_w1=FusedMoEQuantDesc(weight_dtype, w_shape, w1_scale, None, w1_zp, w1_bias),
|
| 692 |
+
_w2=FusedMoEQuantDesc(weight_dtype, w_shape, w2_scale, None, w2_zp, w2_bias),
|
| 693 |
+
)
|
| 694 |
+
|
| 695 |
+
|
| 696 |
+
def mxfp4_w4a16_moe_quant_config(
|
| 697 |
+
w1_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 698 |
+
w2_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 699 |
+
w1_bias: torch.Tensor | None = None,
|
| 700 |
+
w2_bias: torch.Tensor | None = None,
|
| 701 |
+
gemm1_alpha: float | None = None,
|
| 702 |
+
gemm1_beta: float | None = None,
|
| 703 |
+
gemm1_clamp_limit: float | None = None,
|
| 704 |
+
) -> FusedMoEQuantConfig:
|
| 705 |
+
"""
|
| 706 |
+
Construct a quant config for unquantized activations and mxfp4 weights.
|
| 707 |
+
"""
|
| 708 |
+
return FusedMoEQuantConfig(
|
| 709 |
+
_a1=FusedMoEQuantDesc(),
|
| 710 |
+
_a2=FusedMoEQuantDesc(),
|
| 711 |
+
_w1=FusedMoEQuantDesc("mxfp4", None, w1_scale, None, None, w1_bias),
|
| 712 |
+
_w2=FusedMoEQuantDesc("mxfp4", None, w2_scale, None, None, w2_bias),
|
| 713 |
+
gemm1_alpha=gemm1_alpha,
|
| 714 |
+
gemm1_beta=gemm1_beta,
|
| 715 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 716 |
+
)
|
| 717 |
+
|
| 718 |
+
|
| 719 |
+
def mxfp4_mxfp8_moe_quant_config(
|
| 720 |
+
w1_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 721 |
+
w2_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 722 |
+
a1_scale: torch.Tensor | None = None,
|
| 723 |
+
a2_scale: torch.Tensor | None = None,
|
| 724 |
+
w1_bias: torch.Tensor | None = None,
|
| 725 |
+
w2_bias: torch.Tensor | None = None,
|
| 726 |
+
block_shape: list[int] | None = None,
|
| 727 |
+
gemm1_alpha: float | None = None,
|
| 728 |
+
gemm1_beta: float | None = None,
|
| 729 |
+
gemm1_clamp_limit: float | None = None,
|
| 730 |
+
mx_alignment: int = 0,
|
| 731 |
+
is_scale_swizzled: bool = True,
|
| 732 |
+
) -> FusedMoEQuantConfig:
|
| 733 |
+
"""
|
| 734 |
+
Construct a quant config for mxfp4 activations and mxfp4 weights.
|
| 735 |
+
"""
|
| 736 |
+
return FusedMoEQuantConfig(
|
| 737 |
+
_a1=FusedMoEQuantDesc("mxfp8"),
|
| 738 |
+
_a2=FusedMoEQuantDesc("mxfp8"),
|
| 739 |
+
_w1=FusedMoEQuantDesc("mxfp4", None, w1_scale, None, None, w1_bias),
|
| 740 |
+
_w2=FusedMoEQuantDesc("mxfp4", None, w2_scale, None, None, w2_bias),
|
| 741 |
+
gemm1_alpha=gemm1_alpha,
|
| 742 |
+
gemm1_beta=gemm1_beta,
|
| 743 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 744 |
+
mx_alignment=mx_alignment,
|
| 745 |
+
is_scale_swizzled=is_scale_swizzled,
|
| 746 |
+
)
|
| 747 |
+
|
| 748 |
+
|
| 749 |
+
def mxfp4_w4a8_moe_quant_config(
|
| 750 |
+
w1_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 751 |
+
w2_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 752 |
+
a1_scale: torch.Tensor | None = None,
|
| 753 |
+
a2_scale: torch.Tensor | None = None,
|
| 754 |
+
w1_bias: torch.Tensor | None = None,
|
| 755 |
+
w2_bias: torch.Tensor | None = None,
|
| 756 |
+
block_shape: list[int] | None = None,
|
| 757 |
+
gemm1_clamp_limit: float | None = None,
|
| 758 |
+
) -> FusedMoEQuantConfig:
|
| 759 |
+
"""
|
| 760 |
+
Construct a quant config for fp8 activations and mxfp4 weights.
|
| 761 |
+
"""
|
| 762 |
+
return FusedMoEQuantConfig(
|
| 763 |
+
_a1=FusedMoEQuantDesc("fp8", None, a1_scale, None, None, None),
|
| 764 |
+
_a2=FusedMoEQuantDesc("fp8", None, a2_scale, None, None, None),
|
| 765 |
+
_w1=FusedMoEQuantDesc("mxfp4", None, w1_scale, None, None, w1_bias),
|
| 766 |
+
_w2=FusedMoEQuantDesc("mxfp4", None, w2_scale, None, None, w2_bias),
|
| 767 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 768 |
+
)
|
| 769 |
+
|
| 770 |
+
|
| 771 |
+
def ocp_mx_moe_quant_config(
|
| 772 |
+
quant_dtype: str,
|
| 773 |
+
w1_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 774 |
+
w2_scale: Union[torch.Tensor, "PrecisionConfig"],
|
| 775 |
+
weight_dtype: str | None = None,
|
| 776 |
+
a1_scale: torch.Tensor | None = None,
|
| 777 |
+
a2_scale: torch.Tensor | None = None,
|
| 778 |
+
w1_bias: torch.Tensor | None = None,
|
| 779 |
+
w2_bias: torch.Tensor | None = None,
|
| 780 |
+
block_shape: list[int] | None = None,
|
| 781 |
+
gemm1_alpha: float | None = None,
|
| 782 |
+
gemm1_beta: float | None = None,
|
| 783 |
+
gemm1_clamp_limit: float | None = None,
|
| 784 |
+
) -> FusedMoEQuantConfig:
|
| 785 |
+
"""
|
| 786 |
+
Construct a quant config for mxfp4 activations and mxfp4 weights.
|
| 787 |
+
"""
|
| 788 |
+
assert quant_dtype in OCP_MX_DTYPES
|
| 789 |
+
return FusedMoEQuantConfig.make(
|
| 790 |
+
quant_dtype=quant_dtype,
|
| 791 |
+
weight_dtype=weight_dtype,
|
| 792 |
+
w1_scale=w1_scale,
|
| 793 |
+
w2_scale=w2_scale,
|
| 794 |
+
a1_scale=a1_scale,
|
| 795 |
+
a2_scale=a2_scale,
|
| 796 |
+
w1_bias=w1_bias,
|
| 797 |
+
w2_bias=w2_bias,
|
| 798 |
+
per_act_token_quant=False,
|
| 799 |
+
per_out_ch_quant=False,
|
| 800 |
+
block_shape=block_shape,
|
| 801 |
+
gemm1_alpha=gemm1_alpha,
|
| 802 |
+
gemm1_beta=gemm1_beta,
|
| 803 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 804 |
+
)
|
| 805 |
+
|
| 806 |
+
|
| 807 |
+
def nvfp4_moe_quant_config(
|
| 808 |
+
g1_alphas: torch.Tensor,
|
| 809 |
+
g2_alphas: torch.Tensor,
|
| 810 |
+
a1_gscale: torch.Tensor,
|
| 811 |
+
a2_gscale: torch.Tensor,
|
| 812 |
+
w1_scale: torch.Tensor,
|
| 813 |
+
w2_scale: torch.Tensor,
|
| 814 |
+
w1_bias: torch.Tensor | None = None,
|
| 815 |
+
w2_bias: torch.Tensor | None = None,
|
| 816 |
+
is_scale_swizzled: bool = True,
|
| 817 |
+
gemm1_clamp_limit: float | None = None,
|
| 818 |
+
) -> FusedMoEQuantConfig:
|
| 819 |
+
"""
|
| 820 |
+
Construct a quant config for mxfp4 activations and nvp4 weights.
|
| 821 |
+
"""
|
| 822 |
+
return FusedMoEQuantConfig.make(
|
| 823 |
+
"nvfp4",
|
| 824 |
+
w1_scale=w1_scale,
|
| 825 |
+
w2_scale=w2_scale,
|
| 826 |
+
w1_bias=w1_bias,
|
| 827 |
+
w2_bias=w2_bias,
|
| 828 |
+
a1_gscale=a1_gscale,
|
| 829 |
+
a2_gscale=a2_gscale,
|
| 830 |
+
g1_alphas=g1_alphas,
|
| 831 |
+
g2_alphas=g2_alphas,
|
| 832 |
+
per_act_token_quant=False,
|
| 833 |
+
per_out_ch_quant=False,
|
| 834 |
+
block_shape=None,
|
| 835 |
+
is_scale_swizzled=is_scale_swizzled,
|
| 836 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 837 |
+
)
|
| 838 |
+
|
| 839 |
+
|
| 840 |
+
def mxfp4_moe_quant_config(
|
| 841 |
+
w1_scale: torch.Tensor,
|
| 842 |
+
w2_scale: torch.Tensor,
|
| 843 |
+
gemm1_clamp_limit: float | None = None,
|
| 844 |
+
) -> FusedMoEQuantConfig:
|
| 845 |
+
"""
|
| 846 |
+
Construct a quant config for MXFP4 x MXFP4 MoE.
|
| 847 |
+
MXFP4 uses block scaling only (E8M0 scales, 32-element groups), with no
|
| 848 |
+
separate alphas / global activation scales in this config.
|
| 849 |
+
|
| 850 |
+
``gemm1_clamp_limit`` carries a per-layer SwiGLU clamp (Ling-3.0 sets one on
|
| 851 |
+
its last 7 MoE layers). Without it the MXFP4 path silently computes unclamped
|
| 852 |
+
SwiGLU while the BF16 path clamps.
|
| 853 |
+
"""
|
| 854 |
+
return FusedMoEQuantConfig.make(
|
| 855 |
+
"mxfp4",
|
| 856 |
+
w1_scale=w1_scale,
|
| 857 |
+
w2_scale=w2_scale,
|
| 858 |
+
per_act_token_quant=False,
|
| 859 |
+
per_out_ch_quant=False,
|
| 860 |
+
block_shape=None,
|
| 861 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 862 |
+
)
|
| 863 |
+
|
| 864 |
+
|
| 865 |
+
def nvfp4_w4a16_moe_quant_config(
|
| 866 |
+
g1_alphas: torch.Tensor,
|
| 867 |
+
g2_alphas: torch.Tensor,
|
| 868 |
+
w1_scale: torch.Tensor,
|
| 869 |
+
w2_scale: torch.Tensor,
|
| 870 |
+
gemm1_clamp_limit: float | None = None,
|
| 871 |
+
) -> FusedMoEQuantConfig:
|
| 872 |
+
"""
|
| 873 |
+
Construct a quant config for 16-but activations and nvp4 weights.
|
| 874 |
+
"""
|
| 875 |
+
return FusedMoEQuantConfig.make(
|
| 876 |
+
quant_dtype=None,
|
| 877 |
+
w1_scale=w1_scale,
|
| 878 |
+
w2_scale=w2_scale,
|
| 879 |
+
g1_alphas=g1_alphas,
|
| 880 |
+
g2_alphas=g2_alphas,
|
| 881 |
+
weight_dtype="nvfp4",
|
| 882 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 883 |
+
)
|
| 884 |
+
|
| 885 |
+
|
| 886 |
+
def int4_w4a16_moe_quant_config(
|
| 887 |
+
w1_scale: torch.Tensor,
|
| 888 |
+
w2_scale: torch.Tensor,
|
| 889 |
+
w1_zp: torch.Tensor | None = None,
|
| 890 |
+
w2_zp: torch.Tensor | None = None,
|
| 891 |
+
w1_bias: torch.Tensor | None = None,
|
| 892 |
+
w2_bias: torch.Tensor | None = None,
|
| 893 |
+
block_shape: list[int] | None = None,
|
| 894 |
+
a1_gscale: torch.Tensor | None = None,
|
| 895 |
+
a2_gscale: torch.Tensor | None = None,
|
| 896 |
+
gemm1_clamp_limit: float | None = None,
|
| 897 |
+
gemm1_alpha: float | None = None,
|
| 898 |
+
gemm1_beta: float | None = None,
|
| 899 |
+
) -> FusedMoEQuantConfig:
|
| 900 |
+
"""
|
| 901 |
+
Construct a quant config for 16-bit float activations and int4 weights.
|
| 902 |
+
"""
|
| 903 |
+
group_shape = GroupShape(*block_shape) if block_shape is not None else None
|
| 904 |
+
return FusedMoEQuantConfig(
|
| 905 |
+
_a1=FusedMoEQuantDesc(shape=group_shape, alpha_or_gscale=a1_gscale),
|
| 906 |
+
_a2=FusedMoEQuantDesc(shape=group_shape, alpha_or_gscale=a2_gscale),
|
| 907 |
+
_w1=FusedMoEQuantDesc("int4", group_shape, w1_scale, None, w1_zp, w1_bias),
|
| 908 |
+
_w2=FusedMoEQuantDesc("int4", group_shape, w2_scale, None, w2_zp, w2_bias),
|
| 909 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 910 |
+
gemm1_alpha=gemm1_alpha,
|
| 911 |
+
gemm1_beta=gemm1_beta,
|
| 912 |
+
)
|
| 913 |
+
|
| 914 |
+
|
| 915 |
+
def fp8_w8a16_moe_quant_config(
|
| 916 |
+
w1_scale: torch.Tensor,
|
| 917 |
+
w2_scale: torch.Tensor,
|
| 918 |
+
w1_bias: torch.Tensor | None = None,
|
| 919 |
+
w2_bias: torch.Tensor | None = None,
|
| 920 |
+
block_shape: list[int] | None = None,
|
| 921 |
+
gemm1_alpha: float | None = None,
|
| 922 |
+
gemm1_beta: float | None = None,
|
| 923 |
+
gemm1_clamp_limit: float | None = None,
|
| 924 |
+
) -> FusedMoEQuantConfig:
|
| 925 |
+
"""
|
| 926 |
+
Construct a quant config for 16-bit float activations and fp8 weights.
|
| 927 |
+
"""
|
| 928 |
+
group_shape = GroupShape(*block_shape) if block_shape is not None else None
|
| 929 |
+
fp8_dtype = current_platform.fp8_dtype()
|
| 930 |
+
return FusedMoEQuantConfig(
|
| 931 |
+
_a1=FusedMoEQuantDesc(),
|
| 932 |
+
_a2=FusedMoEQuantDesc(),
|
| 933 |
+
_w1=FusedMoEQuantDesc(
|
| 934 |
+
fp8_dtype,
|
| 935 |
+
group_shape,
|
| 936 |
+
w1_scale,
|
| 937 |
+
None,
|
| 938 |
+
None,
|
| 939 |
+
w1_bias,
|
| 940 |
+
),
|
| 941 |
+
_w2=FusedMoEQuantDesc(
|
| 942 |
+
fp8_dtype,
|
| 943 |
+
group_shape,
|
| 944 |
+
w2_scale,
|
| 945 |
+
None,
|
| 946 |
+
None,
|
| 947 |
+
w2_bias,
|
| 948 |
+
),
|
| 949 |
+
gemm1_alpha=gemm1_alpha,
|
| 950 |
+
gemm1_beta=gemm1_beta,
|
| 951 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 952 |
+
)
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
def int8_w8a16_moe_quant_config(
|
| 956 |
+
w1_scale: torch.Tensor,
|
| 957 |
+
w2_scale: torch.Tensor,
|
| 958 |
+
w1_zp: torch.Tensor | None = None,
|
| 959 |
+
w2_zp: torch.Tensor | None = None,
|
| 960 |
+
w1_bias: torch.Tensor | None = None,
|
| 961 |
+
w2_bias: torch.Tensor | None = None,
|
| 962 |
+
block_shape: list[int] | None = None,
|
| 963 |
+
a1_gscale: torch.Tensor | None = None,
|
| 964 |
+
a2_gscale: torch.Tensor | None = None,
|
| 965 |
+
gemm1_clamp_limit: float | None = None,
|
| 966 |
+
gemm1_alpha: float | None = None,
|
| 967 |
+
gemm1_beta: float | None = None,
|
| 968 |
+
) -> FusedMoEQuantConfig:
|
| 969 |
+
"""
|
| 970 |
+
Construct a quant config for 16-bit float activations and int8 weights.
|
| 971 |
+
"""
|
| 972 |
+
group_shape = GroupShape(*block_shape) if block_shape is not None else None
|
| 973 |
+
return FusedMoEQuantConfig(
|
| 974 |
+
_a1=FusedMoEQuantDesc(shape=group_shape, alpha_or_gscale=a1_gscale),
|
| 975 |
+
_a2=FusedMoEQuantDesc(shape=group_shape, alpha_or_gscale=a2_gscale),
|
| 976 |
+
_w1=FusedMoEQuantDesc(torch.int8, group_shape, w1_scale, None, w1_zp, w1_bias),
|
| 977 |
+
_w2=FusedMoEQuantDesc(torch.int8, group_shape, w2_scale, None, w2_zp, w2_bias),
|
| 978 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 979 |
+
gemm1_alpha=gemm1_alpha,
|
| 980 |
+
gemm1_beta=gemm1_beta,
|
| 981 |
+
)
|
| 982 |
+
|
| 983 |
+
|
| 984 |
+
def int4_w4afp8_moe_quant_config(
|
| 985 |
+
w1_scale: torch.Tensor,
|
| 986 |
+
w2_scale: torch.Tensor,
|
| 987 |
+
g1_alphas: torch.Tensor,
|
| 988 |
+
g2_alphas: torch.Tensor,
|
| 989 |
+
per_act_token_quant: bool = False,
|
| 990 |
+
per_out_ch_quant: bool = False,
|
| 991 |
+
block_shape: list[int] | None = None,
|
| 992 |
+
) -> FusedMoEQuantConfig:
|
| 993 |
+
"""
|
| 994 |
+
Construct a quant config for fp8 activations and int4 weights.
|
| 995 |
+
"""
|
| 996 |
+
return FusedMoEQuantConfig.make(
|
| 997 |
+
torch.float8_e4m3fn, # quant dtype for activations
|
| 998 |
+
w1_scale=w1_scale,
|
| 999 |
+
w2_scale=w2_scale,
|
| 1000 |
+
g1_alphas=g1_alphas,
|
| 1001 |
+
g2_alphas=g2_alphas,
|
| 1002 |
+
per_act_token_quant=per_act_token_quant,
|
| 1003 |
+
per_out_ch_quant=per_out_ch_quant,
|
| 1004 |
+
block_shape=block_shape,
|
| 1005 |
+
weight_dtype="int4", # weight dtype for weights
|
| 1006 |
+
)
|
| 1007 |
+
|
| 1008 |
+
|
| 1009 |
+
def biased_moe_quant_config(
|
| 1010 |
+
w1_bias: torch.Tensor | None,
|
| 1011 |
+
w2_bias: torch.Tensor | None,
|
| 1012 |
+
gemm1_alpha: float | None = None,
|
| 1013 |
+
gemm1_beta: float | None = None,
|
| 1014 |
+
gemm1_clamp_limit: float | None = None,
|
| 1015 |
+
) -> FusedMoEQuantConfig:
|
| 1016 |
+
"""
|
| 1017 |
+
Construct a quant config for unquantized activations with biases.
|
| 1018 |
+
|
| 1019 |
+
gemm1_alpha/gemm1_beta/gemm1_clamp_limit carry the SwiGLU gate params
|
| 1020 |
+
through to the fused activation kernel (e.g. swigluoai_uninterleave).
|
| 1021 |
+
"""
|
| 1022 |
+
return FusedMoEQuantConfig(
|
| 1023 |
+
_a1=FusedMoEQuantDesc(),
|
| 1024 |
+
_a2=FusedMoEQuantDesc(),
|
| 1025 |
+
_w1=FusedMoEQuantDesc(bias=w1_bias),
|
| 1026 |
+
_w2=FusedMoEQuantDesc(bias=w2_bias),
|
| 1027 |
+
gemm1_alpha=gemm1_alpha,
|
| 1028 |
+
gemm1_beta=gemm1_beta,
|
| 1029 |
+
gemm1_clamp_limit=gemm1_clamp_limit,
|
| 1030 |
+
)
|
| 1031 |
+
|
| 1032 |
+
|
| 1033 |
+
# A FusedMoEQuantConfig constant for an unquantized MoE op.
|
| 1034 |
+
FUSED_MOE_UNQUANTIZED_CONFIG: FusedMoEQuantConfig = FusedMoEQuantConfig.make()
|
| 1035 |
+
|
| 1036 |
+
|
| 1037 |
+
@dataclass
|
| 1038 |
+
class FusedMoEParallelConfig:
|
| 1039 |
+
tp_size: int
|
| 1040 |
+
pcp_size: int
|
| 1041 |
+
dp_size: int
|
| 1042 |
+
ep_size: int
|
| 1043 |
+
tp_rank: int
|
| 1044 |
+
pcp_rank: int
|
| 1045 |
+
dp_rank: int
|
| 1046 |
+
ep_rank: int
|
| 1047 |
+
sp_size: int
|
| 1048 |
+
|
| 1049 |
+
use_ep: bool # whether to use EP or not
|
| 1050 |
+
all2all_backend: str # all2all backend for MoE communication
|
| 1051 |
+
enable_eplb: bool # whether to enable expert load balancing
|
| 1052 |
+
|
| 1053 |
+
@property
|
| 1054 |
+
def is_sequence_parallel(self) -> bool:
|
| 1055 |
+
return self.sp_size > 1
|
| 1056 |
+
|
| 1057 |
+
@property
|
| 1058 |
+
def use_all2all_kernels(self):
|
| 1059 |
+
return self.use_ep and (
|
| 1060 |
+
self.dp_size > 1 or self.pcp_size > 1 or self.is_sequence_parallel
|
| 1061 |
+
)
|
| 1062 |
+
|
| 1063 |
+
@property
|
| 1064 |
+
def use_deepep_ht_kernels(self):
|
| 1065 |
+
return (
|
| 1066 |
+
self.use_all2all_kernels
|
| 1067 |
+
and self.all2all_backend == "deepep_high_throughput"
|
| 1068 |
+
)
|
| 1069 |
+
|
| 1070 |
+
@property
|
| 1071 |
+
def use_deepep_ll_kernels(self):
|
| 1072 |
+
return self.use_all2all_kernels and self.all2all_backend == "deepep_low_latency"
|
| 1073 |
+
|
| 1074 |
+
@property
|
| 1075 |
+
def use_fi_nvl_two_sided_kernels(self):
|
| 1076 |
+
return self.use_all2all_kernels and (
|
| 1077 |
+
self.all2all_backend == "flashinfer_all2allv"
|
| 1078 |
+
or self.all2all_backend == "flashinfer_nvlink_two_sided"
|
| 1079 |
+
)
|
| 1080 |
+
|
| 1081 |
+
@property
|
| 1082 |
+
def use_fi_nvl_one_sided_kernels(self):
|
| 1083 |
+
return (
|
| 1084 |
+
self.use_all2all_kernels
|
| 1085 |
+
and self.all2all_backend == "flashinfer_nvlink_one_sided"
|
| 1086 |
+
)
|
| 1087 |
+
|
| 1088 |
+
@property
|
| 1089 |
+
def use_batched_activation_format(self):
|
| 1090 |
+
return self.use_deepep_ll_kernels or self.use_nixl_ep_kernels
|
| 1091 |
+
|
| 1092 |
+
@property
|
| 1093 |
+
def needs_round_robin_routing_tables(self):
|
| 1094 |
+
return self.use_deepep_ll_kernels or self.use_nixl_ep_kernels
|
| 1095 |
+
|
| 1096 |
+
@property
|
| 1097 |
+
def use_ag_rs_all2all_kernels(self):
|
| 1098 |
+
return (
|
| 1099 |
+
self.use_all2all_kernels
|
| 1100 |
+
and self.all2all_backend == "allgather_reducescatter"
|
| 1101 |
+
)
|
| 1102 |
+
|
| 1103 |
+
@property
|
| 1104 |
+
def use_mori_kernels(self):
|
| 1105 |
+
return self.use_all2all_kernels and self.all2all_backend in (
|
| 1106 |
+
"mori_high_throughput",
|
| 1107 |
+
"mori_low_latency",
|
| 1108 |
+
)
|
| 1109 |
+
|
| 1110 |
+
@property
|
| 1111 |
+
def use_nixl_ep_kernels(self):
|
| 1112 |
+
return self.use_all2all_kernels and self.all2all_backend == "nixl_ep"
|
| 1113 |
+
|
| 1114 |
+
@property
|
| 1115 |
+
def use_deepep_v2_kernels(self):
|
| 1116 |
+
return self.use_all2all_kernels and self.all2all_backend == "deepep_v2"
|
| 1117 |
+
|
| 1118 |
+
@staticmethod
|
| 1119 |
+
def flatten_tp_across_dp_and_pcp(
|
| 1120 |
+
tp_size: int, dp_size: int, dp_rank: int, pcp_size: int, pcp_rank: int
|
| 1121 |
+
) -> tuple[int, int]:
|
| 1122 |
+
tp_rank = 0 if tp_size == 1 else get_tensor_model_parallel_rank()
|
| 1123 |
+
# There are actually dp_size * pcp_size * tp_size devices.
|
| 1124 |
+
# Update tp_size and tp_rank so we shard across all devices.
|
| 1125 |
+
flatten_tp_size = dp_size * pcp_size * tp_size
|
| 1126 |
+
flatten_tp_rank = dp_rank * pcp_size * tp_size + pcp_rank * tp_size + tp_rank
|
| 1127 |
+
return flatten_tp_size, flatten_tp_rank
|
| 1128 |
+
|
| 1129 |
+
@staticmethod
|
| 1130 |
+
def make(
|
| 1131 |
+
tp_size_: int,
|
| 1132 |
+
pcp_size_: int,
|
| 1133 |
+
dp_size_: int,
|
| 1134 |
+
sp_size_: int,
|
| 1135 |
+
vllm_parallel_config: ParallelConfig,
|
| 1136 |
+
) -> "FusedMoEParallelConfig":
|
| 1137 |
+
"""
|
| 1138 |
+
Determine MoE parallel configuration. Based on the input `tp_size_`,
|
| 1139 |
+
`dp_size_` and vllm's parallel config, determine what
|
| 1140 |
+
level's of parallelism to use in the fused moe layer.
|
| 1141 |
+
|
| 1142 |
+
Args:
|
| 1143 |
+
tp_size_ (int): `tp_size` passed into the FusedMoEFactory constructor.
|
| 1144 |
+
pcp_size_ (int): `pcp_size` passed into the FusedMoEFactory constructor.
|
| 1145 |
+
dp_size_ (int): `dp_size` passed into the FusedMoEFactory constructor.
|
| 1146 |
+
vllm_parallel_config (ParallelConfig): vLLM's parallel config
|
| 1147 |
+
object which contains the `enable_expert_parallel` flag.
|
| 1148 |
+
|
| 1149 |
+
Examples:
|
| 1150 |
+
When there is no parallelism requested,
|
| 1151 |
+
i.e. `tp_size_` = `pcp_size_` = `dp_size_` = 1, we simply return the sizes
|
| 1152 |
+
unaltered and the ranks set to 0.
|
| 1153 |
+
|
| 1154 |
+
Expert Parallelism is considered only when either `dp_size_`, `pcp_size_` or
|
| 1155 |
+
`tp_size_` is non trivial.
|
| 1156 |
+
|
| 1157 |
+
Note that PCP serves the same function as DP here.
|
| 1158 |
+
|
| 1159 |
+
When TP = 2, DP(PCP) = 1 and EP = False, the configuration on different
|
| 1160 |
+
devices:
|
| 1161 |
+
|
| 1162 |
+
- device 0 : TP = {2, 0} DP = {1, 0} EP = {1, 0} //
|
| 1163 |
+
legend : {size, rank}
|
| 1164 |
+
- device 1 : TP = {2, 1} DP = {1, 0} EP = {1, 0}
|
| 1165 |
+
- Comment : Tensors are sharded across 2 devices.
|
| 1166 |
+
|
| 1167 |
+
When TP = 1, DP(PCP) = 2 and EP = False, the configuration on different
|
| 1168 |
+
devices:
|
| 1169 |
+
|
| 1170 |
+
- device 0 : TP = {2, 0} DP = {2, 0} EP = {1, 0}
|
| 1171 |
+
- device 1 : TP = {2, 1} DP = {2, 1} EP = {1, 0}
|
| 1172 |
+
- Comment: There are 2 engine instances and the tensors are sharded
|
| 1173 |
+
across 2 decvices.
|
| 1174 |
+
|
| 1175 |
+
When TP = 2, DP(PCP) = 2 and EP = False, the configuration on different
|
| 1176 |
+
devices:
|
| 1177 |
+
|
| 1178 |
+
- device 0: TP = {4, 0} DP = {2, 0} EP = {1, 0}
|
| 1179 |
+
- device 1: TP = {4, 1} DP = {2, 0} EP = {1, 0}
|
| 1180 |
+
- device 2: TP = {4, 2} DP = {2, 1} EP = {1, 0}
|
| 1181 |
+
- device 3: TP = {4, 3} DP = {2, 1} EP = {1, 0}
|
| 1182 |
+
- Comment: There are 2 engine instances and the tensors are sharded
|
| 1183 |
+
across 4 devices.
|
| 1184 |
+
|
| 1185 |
+
When, TP = 2, DP(PCP) = 1 and EP = True, the configuration on different
|
| 1186 |
+
devices:
|
| 1187 |
+
|
| 1188 |
+
- device 0: TP = {1, 0} DP = {1, 0} EP = {2, 0}
|
| 1189 |
+
- device 1: TP = {1, 0} DP = {1, 0} EP = {2, 1}
|
| 1190 |
+
- Comment: The experts are split between the 2 devices.
|
| 1191 |
+
|
| 1192 |
+
When, TP = 1, DP(PCP) = 2 and EP = True, the configuration on different
|
| 1193 |
+
devices:
|
| 1194 |
+
|
| 1195 |
+
- device 0: TP = {1, 0} DP = {2, 0} EP = {2, 0}
|
| 1196 |
+
- device 1: TP = {1, 0} DP = {2, 1} EP = {2, 1}
|
| 1197 |
+
- Comment: There are 2 engine instances and the experts are split
|
| 1198 |
+
between the 2 devices.
|
| 1199 |
+
|
| 1200 |
+
When TP = 2, DP(PCP) = 2 and EP = True, the configuration on different
|
| 1201 |
+
devices:
|
| 1202 |
+
|
| 1203 |
+
- device 0: TP = {1, 0} DP = {2, 0} EP = {4, 0}
|
| 1204 |
+
- device 1: TP = {1, 0} DP = {2, 0} EP = {4, 1}
|
| 1205 |
+
- device 2: TP = {1, 0} DP = {2, 1} EP = {4, 2}
|
| 1206 |
+
- device 3: TP = {1, 0} DP = {2, 1} EP = {4, 3}
|
| 1207 |
+
- Comment: There are 2 engine instances and the experts are split
|
| 1208 |
+
between the 4 devices.
|
| 1209 |
+
"""
|
| 1210 |
+
use_ep = (
|
| 1211 |
+
dp_size_ * pcp_size_ * tp_size_ > 1
|
| 1212 |
+
and vllm_parallel_config.enable_expert_parallel
|
| 1213 |
+
)
|
| 1214 |
+
|
| 1215 |
+
dp_size = dp_size_
|
| 1216 |
+
dp_rank = get_dp_group().rank_in_group if dp_size > 1 else 0
|
| 1217 |
+
pcp_size = pcp_size_
|
| 1218 |
+
pcp_rank = get_pcp_group().rank_in_group if pcp_size > 1 else 0
|
| 1219 |
+
tp_size, tp_rank = FusedMoEParallelConfig.flatten_tp_across_dp_and_pcp(
|
| 1220 |
+
tp_size_, dp_size_, dp_rank, pcp_size_, pcp_rank
|
| 1221 |
+
)
|
| 1222 |
+
|
| 1223 |
+
if not use_ep:
|
| 1224 |
+
return FusedMoEParallelConfig(
|
| 1225 |
+
tp_size=tp_size,
|
| 1226 |
+
tp_rank=tp_rank,
|
| 1227 |
+
pcp_size=pcp_size,
|
| 1228 |
+
pcp_rank=pcp_rank,
|
| 1229 |
+
dp_size=dp_size,
|
| 1230 |
+
dp_rank=dp_rank,
|
| 1231 |
+
ep_size=1,
|
| 1232 |
+
ep_rank=0,
|
| 1233 |
+
sp_size=sp_size_,
|
| 1234 |
+
use_ep=False,
|
| 1235 |
+
all2all_backend=vllm_parallel_config.all2all_backend,
|
| 1236 |
+
enable_eplb=vllm_parallel_config.enable_eplb,
|
| 1237 |
+
)
|
| 1238 |
+
# DP + EP / TP + EP / DP + TP + EP
|
| 1239 |
+
assert use_ep
|
| 1240 |
+
# In EP, each device owns a set of experts fully. There is no tensor
|
| 1241 |
+
# parallel update tp_size, tp_rank, ep_size and ep_rank to reflect that.
|
| 1242 |
+
ep_size = tp_size
|
| 1243 |
+
ep_rank = tp_rank
|
| 1244 |
+
return FusedMoEParallelConfig(
|
| 1245 |
+
tp_size=1,
|
| 1246 |
+
tp_rank=0,
|
| 1247 |
+
pcp_size=pcp_size,
|
| 1248 |
+
pcp_rank=pcp_rank,
|
| 1249 |
+
dp_size=dp_size,
|
| 1250 |
+
dp_rank=dp_rank,
|
| 1251 |
+
ep_size=ep_size,
|
| 1252 |
+
ep_rank=ep_rank,
|
| 1253 |
+
sp_size=sp_size_,
|
| 1254 |
+
use_ep=True,
|
| 1255 |
+
all2all_backend=vllm_parallel_config.all2all_backend,
|
| 1256 |
+
enable_eplb=vllm_parallel_config.enable_eplb,
|
| 1257 |
+
)
|
| 1258 |
+
|
| 1259 |
+
@classmethod
|
| 1260 |
+
def make_no_parallel(cls) -> "FusedMoEParallelConfig":
|
| 1261 |
+
"""For usage in CI/CD and testing."""
|
| 1262 |
+
return FusedMoEParallelConfig(
|
| 1263 |
+
tp_size=1,
|
| 1264 |
+
tp_rank=0,
|
| 1265 |
+
pcp_size=1,
|
| 1266 |
+
pcp_rank=0,
|
| 1267 |
+
dp_size=1,
|
| 1268 |
+
dp_rank=0,
|
| 1269 |
+
ep_size=1,
|
| 1270 |
+
ep_rank=0,
|
| 1271 |
+
sp_size=1,
|
| 1272 |
+
use_ep=False,
|
| 1273 |
+
all2all_backend="allgather_reducescatter",
|
| 1274 |
+
enable_eplb=False,
|
| 1275 |
+
)
|
| 1276 |
+
|
| 1277 |
+
|
| 1278 |
+
# Adapted from pplx-kernels tests/all_to_all_utils.py
|
| 1279 |
+
@dataclass
|
| 1280 |
+
class FusedMoEConfig:
|
| 1281 |
+
num_experts: int
|
| 1282 |
+
experts_per_token: int
|
| 1283 |
+
hidden_dim: int
|
| 1284 |
+
intermediate_size: int
|
| 1285 |
+
num_local_experts: int
|
| 1286 |
+
num_logical_experts: int
|
| 1287 |
+
activation: MoEActivation
|
| 1288 |
+
device: torch.device | str
|
| 1289 |
+
routing_method: RoutingMethodType
|
| 1290 |
+
moe_parallel_config: FusedMoEParallelConfig
|
| 1291 |
+
|
| 1292 |
+
# The activation type.
|
| 1293 |
+
in_dtype: torch.dtype
|
| 1294 |
+
|
| 1295 |
+
# Defaults to in_dtype if not specified.
|
| 1296 |
+
router_logits_dtype: torch.dtype | None = None
|
| 1297 |
+
|
| 1298 |
+
# Defaults to hidden_dim if not specified.
|
| 1299 |
+
hidden_dim_unpadded: int | None = None
|
| 1300 |
+
# Defaults to intermediate_size_per_partition if not specified.
|
| 1301 |
+
intermediate_size_per_partition_unpadded: int | None = None
|
| 1302 |
+
# Model specific override
|
| 1303 |
+
intermediate_pad: int | None = None
|
| 1304 |
+
|
| 1305 |
+
moe_backend: MoEBackend = "auto"
|
| 1306 |
+
max_num_tokens: int = SchedulerConfig.DEFAULT_MAX_NUM_BATCHED_TOKENS_FOR_BATCHED_DP
|
| 1307 |
+
has_bias: bool = False
|
| 1308 |
+
is_lora_enabled: bool = False
|
| 1309 |
+
|
| 1310 |
+
# When True, the MoE skips its final cross-rank all-reduce (and the separate
|
| 1311 |
+
# shared-expert reduce), returning the partial per-rank sum. The caller is
|
| 1312 |
+
# then responsible for the reduction (e.g. fusing it into the next RMSNorm).
|
| 1313 |
+
# Only honored on the non-reduced (late-AR) TP path. Default False.
|
| 1314 |
+
skip_final_all_reduce: bool = False
|
| 1315 |
+
|
| 1316 |
+
# SwiGLU clamp limit. When set, backends that do not implement the clamp
|
| 1317 |
+
# are filtered out by `FusedMoEExperts.is_supported_config` so the oracle
|
| 1318 |
+
# cannot silently select one and drop the clamp.
|
| 1319 |
+
swiglu_limit: float | None = None
|
| 1320 |
+
swiglu_alpha: float | None = None
|
| 1321 |
+
swiglu_beta: float | None = None
|
| 1322 |
+
|
| 1323 |
+
# SituGLU parameters used by Kimi sit(u/v2) activations.
|
| 1324 |
+
activation_situ_beta: float | None = None
|
| 1325 |
+
activation_situ_linear_beta: float | None = None
|
| 1326 |
+
|
| 1327 |
+
max_capture_size: int = 0
|
| 1328 |
+
|
| 1329 |
+
# Set by __post_init__
|
| 1330 |
+
intermediate_size_per_partition: int = -1
|
| 1331 |
+
rocm_aiter_fmoe_enabled: bool = False
|
| 1332 |
+
aiter_fmoe_shared_expert_enabled: bool = False
|
| 1333 |
+
|
| 1334 |
+
def __post_init__(self):
|
| 1335 |
+
from vllm._aiter_ops import rocm_aiter_ops
|
| 1336 |
+
|
| 1337 |
+
tp_size = self.moe_parallel_config.tp_size
|
| 1338 |
+
assert self.intermediate_size % tp_size == 0
|
| 1339 |
+
self.intermediate_size_per_partition = self.intermediate_size // tp_size
|
| 1340 |
+
|
| 1341 |
+
if self.dp_size > 1:
|
| 1342 |
+
logger.debug_once(
|
| 1343 |
+
"Using FusedMoEConfig::max_num_tokens=%d", self.max_num_tokens
|
| 1344 |
+
)
|
| 1345 |
+
|
| 1346 |
+
assert self.max_num_tokens > 0
|
| 1347 |
+
|
| 1348 |
+
if self.router_logits_dtype is None:
|
| 1349 |
+
self.router_logits_dtype = self.in_dtype
|
| 1350 |
+
|
| 1351 |
+
if self.hidden_dim_unpadded is None:
|
| 1352 |
+
self.hidden_dim_unpadded = self.hidden_dim
|
| 1353 |
+
if self.intermediate_size_per_partition_unpadded is None:
|
| 1354 |
+
self.intermediate_size_per_partition_unpadded = (
|
| 1355 |
+
self.intermediate_size_per_partition
|
| 1356 |
+
)
|
| 1357 |
+
|
| 1358 |
+
if self.is_act_and_mul:
|
| 1359 |
+
self.rocm_aiter_fmoe_enabled = rocm_aiter_ops.is_fused_moe_enabled()
|
| 1360 |
+
self.aiter_fmoe_shared_expert_enabled = (
|
| 1361 |
+
rocm_aiter_ops.is_fusion_moe_shared_experts_enabled()
|
| 1362 |
+
)
|
| 1363 |
+
|
| 1364 |
+
if self.use_mori_kernels:
|
| 1365 |
+
assert self.rocm_aiter_fmoe_enabled, (
|
| 1366 |
+
"Mori needs to be used with aiter fused_moe for now."
|
| 1367 |
+
)
|
| 1368 |
+
assert not self.aiter_fmoe_shared_expert_enabled, (
|
| 1369 |
+
"Mori does not support fusion shared expert now. "
|
| 1370 |
+
"Turn it off by setting VLLM_ROCM_USE_AITER_FUSION_SHARED_EXPERTS=0"
|
| 1371 |
+
)
|
| 1372 |
+
|
| 1373 |
+
if not self.is_act_and_mul and not (
|
| 1374 |
+
current_platform.is_cuda_alike() or current_platform.is_xpu()
|
| 1375 |
+
):
|
| 1376 |
+
raise NotImplementedError(
|
| 1377 |
+
"is_act_and_mul=False is supported only for CUDA, XPU and ROCm for now"
|
| 1378 |
+
)
|
| 1379 |
+
|
| 1380 |
+
@property
|
| 1381 |
+
def is_act_and_mul(self) -> bool:
|
| 1382 |
+
return self.activation.is_gated
|
| 1383 |
+
|
| 1384 |
+
@property
|
| 1385 |
+
def tp_size(self):
|
| 1386 |
+
return self.moe_parallel_config.tp_size
|
| 1387 |
+
|
| 1388 |
+
@property
|
| 1389 |
+
def dp_size(self):
|
| 1390 |
+
return self.moe_parallel_config.dp_size
|
| 1391 |
+
|
| 1392 |
+
@property
|
| 1393 |
+
def pcp_size(self):
|
| 1394 |
+
return self.moe_parallel_config.pcp_size
|
| 1395 |
+
|
| 1396 |
+
@property
|
| 1397 |
+
def ep_size(self):
|
| 1398 |
+
return self.moe_parallel_config.ep_size
|
| 1399 |
+
|
| 1400 |
+
@property
|
| 1401 |
+
def sp_size(self):
|
| 1402 |
+
return self.moe_parallel_config.sp_size
|
| 1403 |
+
|
| 1404 |
+
@property
|
| 1405 |
+
def is_sequence_parallel(self):
|
| 1406 |
+
return self.moe_parallel_config.is_sequence_parallel
|
| 1407 |
+
|
| 1408 |
+
@property
|
| 1409 |
+
def tp_rank(self):
|
| 1410 |
+
return self.moe_parallel_config.tp_rank
|
| 1411 |
+
|
| 1412 |
+
@property
|
| 1413 |
+
def dp_rank(self):
|
| 1414 |
+
return self.moe_parallel_config.dp_rank
|
| 1415 |
+
|
| 1416 |
+
@property
|
| 1417 |
+
def pcp_rank(self):
|
| 1418 |
+
return self.moe_parallel_config.pcp_rank
|
| 1419 |
+
|
| 1420 |
+
@property
|
| 1421 |
+
def ep_rank(self):
|
| 1422 |
+
return self.moe_parallel_config.ep_rank
|
| 1423 |
+
|
| 1424 |
+
@property
|
| 1425 |
+
def use_ep(self):
|
| 1426 |
+
return self.moe_parallel_config.use_ep
|
| 1427 |
+
|
| 1428 |
+
@property
|
| 1429 |
+
def use_deepep_ht_kernels(self):
|
| 1430 |
+
return self.moe_parallel_config.use_deepep_ht_kernels
|
| 1431 |
+
|
| 1432 |
+
@property
|
| 1433 |
+
def use_deepep_ll_kernels(self):
|
| 1434 |
+
return self.moe_parallel_config.use_deepep_ll_kernels
|
| 1435 |
+
|
| 1436 |
+
@property
|
| 1437 |
+
def use_mori_kernels(self):
|
| 1438 |
+
return self.moe_parallel_config.use_mori_kernels
|
| 1439 |
+
|
| 1440 |
+
@property
|
| 1441 |
+
def use_fi_nvl_two_sided_kernels(self):
|
| 1442 |
+
return self.moe_parallel_config.use_fi_nvl_two_sided_kernels
|
| 1443 |
+
|
| 1444 |
+
@property
|
| 1445 |
+
def use_fi_nvl_one_sided_kernels(self):
|
| 1446 |
+
return self.moe_parallel_config.use_fi_nvl_one_sided_kernels
|
| 1447 |
+
|
| 1448 |
+
@property
|
| 1449 |
+
def use_ag_rs_all2all_kernels(self):
|
| 1450 |
+
return self.moe_parallel_config.use_ag_rs_all2all_kernels
|
| 1451 |
+
|
| 1452 |
+
@property
|
| 1453 |
+
def use_nixl_ep_kernels(self):
|
| 1454 |
+
return self.moe_parallel_config.use_nixl_ep_kernels
|
| 1455 |
+
|
| 1456 |
+
@property
|
| 1457 |
+
def use_deepep_v2_kernels(self):
|
| 1458 |
+
return self.moe_parallel_config.use_deepep_v2_kernels
|
| 1459 |
+
|
| 1460 |
+
@property
|
| 1461 |
+
def needs_round_robin_routing_tables(self):
|
| 1462 |
+
return self.moe_parallel_config.needs_round_robin_routing_tables
|
vllm_patch/cutlass_moe.py
ADDED
|
@@ -0,0 +1,1441 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
| 3 |
+
"""CUTLASS based Fused MoE kernels."""
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
|
| 7 |
+
import vllm.model_executor.layers.fused_moe.modular_kernel as mk
|
| 8 |
+
from vllm import _custom_ops as ops
|
| 9 |
+
from vllm.logger import init_logger
|
| 10 |
+
from vllm.model_executor.layers.fused_moe.activation import (
|
| 11 |
+
MoEActivation,
|
| 12 |
+
apply_moe_activation,
|
| 13 |
+
)
|
| 14 |
+
from vllm.model_executor.layers.fused_moe.config import (
|
| 15 |
+
FusedMoEConfig,
|
| 16 |
+
FusedMoEParallelConfig,
|
| 17 |
+
FusedMoEQuantConfig,
|
| 18 |
+
)
|
| 19 |
+
from vllm.model_executor.layers.fused_moe.moe_permute_unpermute import (
|
| 20 |
+
MoEPermuteScratch,
|
| 21 |
+
moe_permute,
|
| 22 |
+
moe_permute_unpermute_supported,
|
| 23 |
+
moe_unpermute,
|
| 24 |
+
)
|
| 25 |
+
from vllm.model_executor.layers.fused_moe.topk_weight_and_reduce import (
|
| 26 |
+
TopKWeightAndReduceDelegate,
|
| 27 |
+
TopKWeightAndReduceNoOP,
|
| 28 |
+
)
|
| 29 |
+
from vllm.model_executor.layers.fused_moe.utils import (
|
| 30 |
+
_resize_cache,
|
| 31 |
+
)
|
| 32 |
+
from vllm.model_executor.layers.quantization.utils.quant_utils import (
|
| 33 |
+
QuantKey,
|
| 34 |
+
kFp8DynamicTensorSym,
|
| 35 |
+
kFp8DynamicTokenSym,
|
| 36 |
+
kFp8StaticChannelSym,
|
| 37 |
+
kFp8StaticTensorSym,
|
| 38 |
+
kInt4Static,
|
| 39 |
+
kMxfp4Dynamic,
|
| 40 |
+
kMxfp4Static,
|
| 41 |
+
kNvfp4Dynamic,
|
| 42 |
+
kNvfp4Static,
|
| 43 |
+
)
|
| 44 |
+
from vllm.model_executor.layers.quantization.utils.w8a8_utils import (
|
| 45 |
+
cutlass_group_gemm_supported,
|
| 46 |
+
)
|
| 47 |
+
from vllm.platforms import current_platform
|
| 48 |
+
from vllm.scalar_type import scalar_types
|
| 49 |
+
|
| 50 |
+
logger = init_logger(__name__)
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def run_cutlass_moe_fp8(
|
| 54 |
+
output: torch.Tensor,
|
| 55 |
+
hidden_states: torch.Tensor,
|
| 56 |
+
w1: torch.Tensor,
|
| 57 |
+
w2: torch.Tensor,
|
| 58 |
+
topk_ids: torch.Tensor,
|
| 59 |
+
activation: MoEActivation,
|
| 60 |
+
global_num_experts: int,
|
| 61 |
+
expert_map: torch.Tensor | None,
|
| 62 |
+
w1_scale: torch.Tensor | None,
|
| 63 |
+
w2_scale: torch.Tensor | None,
|
| 64 |
+
a1q_scale: torch.Tensor | None,
|
| 65 |
+
a2_scale: torch.Tensor | None,
|
| 66 |
+
ab_strides1: torch.Tensor,
|
| 67 |
+
ab_strides2: torch.Tensor,
|
| 68 |
+
c_strides1: torch.Tensor,
|
| 69 |
+
c_strides2: torch.Tensor,
|
| 70 |
+
workspace13: torch.Tensor,
|
| 71 |
+
workspace2: torch.Tensor,
|
| 72 |
+
expert_num_tokens: torch.Tensor | None,
|
| 73 |
+
out_dtype: torch.dtype,
|
| 74 |
+
per_act_token: bool,
|
| 75 |
+
per_out_ch: bool,
|
| 76 |
+
use_batched_format: bool,
|
| 77 |
+
topk_weights: torch.Tensor | None,
|
| 78 |
+
permute_scratch: MoEPermuteScratch | None,
|
| 79 |
+
):
|
| 80 |
+
a1q = hidden_states
|
| 81 |
+
|
| 82 |
+
assert activation.is_gated, "Only gated activation is supported"
|
| 83 |
+
assert w1_scale is not None
|
| 84 |
+
assert w2_scale is not None
|
| 85 |
+
assert w1.dtype == torch.float8_e4m3fn
|
| 86 |
+
assert w2.dtype == torch.float8_e4m3fn
|
| 87 |
+
assert a1q.size(-1) == w1.size(2), "Hidden size mismatch w1"
|
| 88 |
+
assert w1.size(1) == w2.size(2) * 2, "Hidden size mismatch w2"
|
| 89 |
+
assert (
|
| 90 |
+
w1_scale.dim() == 1 or w1_scale.size(1) == 1 or w1_scale.shape[1] == w1.size(1)
|
| 91 |
+
), "W1 scale shape mismatch"
|
| 92 |
+
assert (
|
| 93 |
+
w2_scale.dim() == 1 or w2_scale.size(1) == 1 or w2_scale.shape[1] == w2.size(1)
|
| 94 |
+
), "W2 scale shape mismatch"
|
| 95 |
+
assert w1.size(0) == w2.size(0), "Expert number mismatch"
|
| 96 |
+
assert (
|
| 97 |
+
a1q_scale is None
|
| 98 |
+
or a1q_scale.dim() == 0
|
| 99 |
+
or a1q_scale.size(0) == 1
|
| 100 |
+
or a1q_scale.size(0) == a1q.shape[0]
|
| 101 |
+
), "Input scale shape mismatch"
|
| 102 |
+
assert w1.size(0) == w2.size(0), "Weights expert number mismatch"
|
| 103 |
+
assert w1.size(0) == w1_scale.size(0), "w1 scales expert number mismatch"
|
| 104 |
+
assert w1.size(0) == w2_scale.size(0), "w2 scales expert number mismatch"
|
| 105 |
+
assert (
|
| 106 |
+
a2_scale is None
|
| 107 |
+
or a2_scale.dim() == 0
|
| 108 |
+
or a2_scale.size(0) == 1
|
| 109 |
+
or a2_scale.size(0) == a1q.shape[0]
|
| 110 |
+
), "Intermediate scale shape mismatch"
|
| 111 |
+
assert out_dtype in [torch.half, torch.bfloat16], "Invalid output dtype"
|
| 112 |
+
|
| 113 |
+
# NOTE(rob): the expert_map is used for the STANDARD case and
|
| 114 |
+
# the batched format is used by the BATCHED case.
|
| 115 |
+
# TODO(rob): update the MK interface to only pass the expert_map
|
| 116 |
+
# during the STANDARD case to make this clearer across all kernels.
|
| 117 |
+
if use_batched_format:
|
| 118 |
+
assert expert_num_tokens is not None
|
| 119 |
+
else:
|
| 120 |
+
assert expert_num_tokens is None
|
| 121 |
+
|
| 122 |
+
# We have two modes: batched experts and non-batched experts.
|
| 123 |
+
# In the non-batched mode, the input tokens are not padded: thus, the shape
|
| 124 |
+
# of the input is [total_num_tokens, hidden_size]. The input and output
|
| 125 |
+
# require shuffling by a_map and c_map such that the tokens assigned to
|
| 126 |
+
# each expert are contiguous.
|
| 127 |
+
# In the batched mode, the input tokens are padded per expert to ensure that
|
| 128 |
+
# the batched dispatch and combine functions work correctly: thus, the shape
|
| 129 |
+
# of the input is [num_experts, max_num_tokens_per_expert, hidden_size].
|
| 130 |
+
# The batched input and output require no shuffling by a_map and c_map since
|
| 131 |
+
# their tokens are already contiguous for each expert as a result of
|
| 132 |
+
# the dispatch function.
|
| 133 |
+
|
| 134 |
+
M = a1q.size(0) # non batched expert M
|
| 135 |
+
padded_M = a1q.size(1) # batched expert M
|
| 136 |
+
_, K, N = w2.shape
|
| 137 |
+
device = a1q.device
|
| 138 |
+
|
| 139 |
+
assert w1.size(2) == K
|
| 140 |
+
assert global_num_experts != -1
|
| 141 |
+
assert a1q_scale is not None
|
| 142 |
+
|
| 143 |
+
topk = topk_ids.size(1)
|
| 144 |
+
local_E = w1.size(0)
|
| 145 |
+
|
| 146 |
+
if use_batched_format:
|
| 147 |
+
mm1_out = _resize_cache(workspace13, (local_E * padded_M, N * 2))
|
| 148 |
+
act_out = _resize_cache(workspace2, (local_E * padded_M, N))
|
| 149 |
+
quant_out = _resize_cache(
|
| 150 |
+
workspace13.view(dtype=torch.float8_e4m3fn), (local_E * padded_M, N)
|
| 151 |
+
)
|
| 152 |
+
mm2_out = _resize_cache(workspace2, (local_E * padded_M, K))
|
| 153 |
+
else:
|
| 154 |
+
a1q_perm = _resize_cache(
|
| 155 |
+
workspace2.view(dtype=torch.float8_e4m3fn), (M * topk, K)
|
| 156 |
+
)
|
| 157 |
+
mm1_out = _resize_cache(workspace13, (M * topk, N * 2))
|
| 158 |
+
act_out = _resize_cache(workspace2, (M * topk, N))
|
| 159 |
+
# original workspace are based on input hidden_states dtype (bf16)
|
| 160 |
+
quant_out = _resize_cache(
|
| 161 |
+
workspace13.view(dtype=torch.float8_e4m3fn), (M * topk, N)
|
| 162 |
+
)
|
| 163 |
+
mm2_out = _resize_cache(workspace2, (M * topk, K))
|
| 164 |
+
|
| 165 |
+
if use_batched_format:
|
| 166 |
+
assert expert_num_tokens is not None
|
| 167 |
+
|
| 168 |
+
expert_offsets = torch.empty((local_E), dtype=torch.int32, device=device)
|
| 169 |
+
problem_sizes1 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 170 |
+
problem_sizes2 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 171 |
+
|
| 172 |
+
ops.get_cutlass_batched_moe_mm_data(
|
| 173 |
+
expert_offsets,
|
| 174 |
+
problem_sizes1,
|
| 175 |
+
problem_sizes2,
|
| 176 |
+
expert_num_tokens,
|
| 177 |
+
local_E,
|
| 178 |
+
padded_M,
|
| 179 |
+
N,
|
| 180 |
+
K,
|
| 181 |
+
)
|
| 182 |
+
|
| 183 |
+
w1_scale = w1_scale.reshape(w1_scale.size(0), -1)
|
| 184 |
+
w2_scale = w2_scale.reshape(w2_scale.size(0), -1)
|
| 185 |
+
a1q = a1q.reshape(-1, a1q.size(2))
|
| 186 |
+
a1q_scale = a1q_scale.reshape(-1, a1q_scale.size(2)).contiguous()
|
| 187 |
+
# c3x get_group_gemm_starts expects int64 to avoid overflow
|
| 188 |
+
# during offset calculations
|
| 189 |
+
expert_offsets = expert_offsets.to(torch.int64)
|
| 190 |
+
else:
|
| 191 |
+
problem_sizes1 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 192 |
+
problem_sizes2 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 193 |
+
|
| 194 |
+
num_expert = global_num_experts if expert_map is None else expert_map.size(0)
|
| 195 |
+
# permuted a1q reuses workspace2
|
| 196 |
+
a1q, a1q_scale, expert_first_token_offset, inv_perm, _ = moe_permute(
|
| 197 |
+
a1q,
|
| 198 |
+
a1q_scale,
|
| 199 |
+
topk_ids,
|
| 200 |
+
num_expert,
|
| 201 |
+
local_E,
|
| 202 |
+
expert_map,
|
| 203 |
+
permuted_hidden_states=a1q_perm,
|
| 204 |
+
scratch=permute_scratch,
|
| 205 |
+
)
|
| 206 |
+
# swap_ab is a CUTLASS grouped-GEMM optimization (M <= 64 reduces padding).
|
| 207 |
+
swap_ab = a1q.size(0) <= 64
|
| 208 |
+
ops.get_cutlass_moe_mm_problem_sizes_from_expert_offsets(
|
| 209 |
+
expert_first_token_offset, problem_sizes1, problem_sizes2, N, K, swap_ab
|
| 210 |
+
)
|
| 211 |
+
expert_offsets = expert_first_token_offset[:-1]
|
| 212 |
+
|
| 213 |
+
if not per_act_token and (expert_map is not None or use_batched_format):
|
| 214 |
+
# this is necessary to avoid imprecise scale calculation caused by
|
| 215 |
+
# random data in the unused workspace. The workspace is unused when
|
| 216 |
+
# this rank handles only partial tokens, or when it is batched .
|
| 217 |
+
mm1_out.fill_(0)
|
| 218 |
+
|
| 219 |
+
ops.cutlass_moe_mm(
|
| 220 |
+
mm1_out,
|
| 221 |
+
a1q,
|
| 222 |
+
w1,
|
| 223 |
+
a1q_scale,
|
| 224 |
+
w1_scale,
|
| 225 |
+
expert_offsets,
|
| 226 |
+
problem_sizes1,
|
| 227 |
+
ab_strides1,
|
| 228 |
+
ab_strides1,
|
| 229 |
+
c_strides1,
|
| 230 |
+
per_act_token,
|
| 231 |
+
per_out_ch,
|
| 232 |
+
)
|
| 233 |
+
|
| 234 |
+
apply_moe_activation(activation, act_out, mm1_out)
|
| 235 |
+
|
| 236 |
+
a2q, a2q_scale = ops.scaled_fp8_quant(
|
| 237 |
+
act_out, a2_scale, use_per_token_if_dynamic=per_act_token, output=quant_out
|
| 238 |
+
)
|
| 239 |
+
|
| 240 |
+
ops.cutlass_moe_mm(
|
| 241 |
+
mm2_out,
|
| 242 |
+
a2q,
|
| 243 |
+
w2,
|
| 244 |
+
a2q_scale,
|
| 245 |
+
w2_scale,
|
| 246 |
+
expert_offsets,
|
| 247 |
+
problem_sizes2,
|
| 248 |
+
ab_strides2,
|
| 249 |
+
ab_strides2,
|
| 250 |
+
c_strides2,
|
| 251 |
+
per_act_token,
|
| 252 |
+
per_out_ch,
|
| 253 |
+
)
|
| 254 |
+
|
| 255 |
+
if use_batched_format:
|
| 256 |
+
output.copy_(mm2_out.reshape(local_E, padded_M, K), non_blocking=True)
|
| 257 |
+
else:
|
| 258 |
+
# for non-chunking mode the output is resized from workspace13
|
| 259 |
+
# so we need to make sure mm2_out uses workspace2.
|
| 260 |
+
moe_unpermute(
|
| 261 |
+
out=output,
|
| 262 |
+
permuted_hidden_states=mm2_out,
|
| 263 |
+
topk_weights=topk_weights,
|
| 264 |
+
inv_permuted_idx=inv_perm,
|
| 265 |
+
expert_first_token_offset=expert_first_token_offset,
|
| 266 |
+
)
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
class CutlassExpertsFp8Base(mk.FusedMoEExpertsModular):
|
| 270 |
+
def __init__(
|
| 271 |
+
self,
|
| 272 |
+
moe_config: FusedMoEConfig,
|
| 273 |
+
quant_config: FusedMoEQuantConfig,
|
| 274 |
+
max_num_tokens: int | None = None,
|
| 275 |
+
num_dispatchers: int | None = None,
|
| 276 |
+
):
|
| 277 |
+
super().__init__(
|
| 278 |
+
moe_config=moe_config,
|
| 279 |
+
quant_config=quant_config,
|
| 280 |
+
max_num_tokens=max_num_tokens,
|
| 281 |
+
num_dispatchers=num_dispatchers,
|
| 282 |
+
)
|
| 283 |
+
assert quant_config.use_fp8_w8a8
|
| 284 |
+
|
| 285 |
+
e = moe_config.num_local_experts
|
| 286 |
+
n = moe_config.intermediate_size_per_partition
|
| 287 |
+
k = moe_config.hidden_dim
|
| 288 |
+
device = moe_config.device
|
| 289 |
+
ab_strides1_c_strides2 = torch.full((e,), k, device=device, dtype=torch.int64)
|
| 290 |
+
ab_strides2 = torch.full((e,), n, device=device, dtype=torch.int64)
|
| 291 |
+
c_strides1 = torch.full((e,), 2 * n, device=device, dtype=torch.int64)
|
| 292 |
+
|
| 293 |
+
self.out_dtype = moe_config.in_dtype
|
| 294 |
+
self.ab_strides1 = ab_strides1_c_strides2
|
| 295 |
+
self.ab_strides2 = ab_strides2
|
| 296 |
+
self.c_strides1 = c_strides1
|
| 297 |
+
self.c_strides2 = ab_strides1_c_strides2
|
| 298 |
+
self._permute_scratch: MoEPermuteScratch | None = None
|
| 299 |
+
|
| 300 |
+
@staticmethod
|
| 301 |
+
def _supports_current_device() -> bool:
|
| 302 |
+
return cutlass_group_gemm_supported()
|
| 303 |
+
|
| 304 |
+
@staticmethod
|
| 305 |
+
def _supports_no_act_and_mul() -> bool:
|
| 306 |
+
return False
|
| 307 |
+
|
| 308 |
+
@staticmethod
|
| 309 |
+
def _supports_quant_scheme(
|
| 310 |
+
weight_key: QuantKey | None,
|
| 311 |
+
activation_key: QuantKey | None,
|
| 312 |
+
) -> bool:
|
| 313 |
+
SUPPORTED_W_A = [
|
| 314 |
+
(kFp8StaticChannelSym, kFp8DynamicTokenSym),
|
| 315 |
+
(kFp8StaticTensorSym, kFp8DynamicTensorSym),
|
| 316 |
+
(kFp8StaticTensorSym, kFp8StaticTensorSym),
|
| 317 |
+
]
|
| 318 |
+
return (weight_key, activation_key) in SUPPORTED_W_A
|
| 319 |
+
|
| 320 |
+
@staticmethod
|
| 321 |
+
def _supports_activation(activation: MoEActivation) -> bool:
|
| 322 |
+
return activation in [
|
| 323 |
+
MoEActivation.SILU,
|
| 324 |
+
MoEActivation.GELU,
|
| 325 |
+
MoEActivation.GELU_TANH,
|
| 326 |
+
MoEActivation.SWIGLUOAI,
|
| 327 |
+
]
|
| 328 |
+
|
| 329 |
+
def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
|
| 330 |
+
# Let PrepareAndFinalize::finalize() decide the impl.
|
| 331 |
+
return TopKWeightAndReduceDelegate()
|
| 332 |
+
|
| 333 |
+
def _get_permute_scratch(self) -> MoEPermuteScratch | None:
|
| 334 |
+
if self._permute_scratch is None and moe_permute_unpermute_supported():
|
| 335 |
+
self._permute_scratch = MoEPermuteScratch(
|
| 336 |
+
max_num_tokens=self.moe_config.max_num_tokens,
|
| 337 |
+
topk=self.moe_config.experts_per_token,
|
| 338 |
+
num_experts=self.moe_config.num_experts,
|
| 339 |
+
num_local_experts=self.moe_config.num_local_experts,
|
| 340 |
+
device=torch.device(self.moe_config.device),
|
| 341 |
+
)
|
| 342 |
+
return self._permute_scratch
|
| 343 |
+
|
| 344 |
+
def apply(
|
| 345 |
+
self,
|
| 346 |
+
output: torch.Tensor,
|
| 347 |
+
hidden_states: torch.Tensor,
|
| 348 |
+
w1: torch.Tensor,
|
| 349 |
+
w2: torch.Tensor,
|
| 350 |
+
topk_weights: torch.Tensor,
|
| 351 |
+
topk_ids: torch.Tensor,
|
| 352 |
+
activation: MoEActivation,
|
| 353 |
+
global_num_experts: int,
|
| 354 |
+
expert_map: torch.Tensor | None,
|
| 355 |
+
a1q_scale: torch.Tensor | None,
|
| 356 |
+
a2_scale: torch.Tensor | None,
|
| 357 |
+
workspace13: torch.Tensor,
|
| 358 |
+
workspace2: torch.Tensor,
|
| 359 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 360 |
+
apply_router_weight_on_input: bool,
|
| 361 |
+
):
|
| 362 |
+
assert self.w1_zp is None, "w1_zp is not supported in CUTLASS MoE"
|
| 363 |
+
assert self.w2_zp is None, "w2_zp is not supported in CUTLASS MoE"
|
| 364 |
+
|
| 365 |
+
expert_num_tokens = None
|
| 366 |
+
if expert_tokens_meta is not None:
|
| 367 |
+
expert_num_tokens = expert_tokens_meta.expert_num_tokens
|
| 368 |
+
|
| 369 |
+
use_batched_format = (
|
| 370 |
+
self.activation_format() == mk.FusedMoEActivationFormat.BatchedExperts
|
| 371 |
+
)
|
| 372 |
+
|
| 373 |
+
in_dtype = hidden_states.dtype
|
| 374 |
+
run_cutlass_moe_fp8(
|
| 375 |
+
output,
|
| 376 |
+
hidden_states,
|
| 377 |
+
w1,
|
| 378 |
+
w2,
|
| 379 |
+
topk_ids,
|
| 380 |
+
activation,
|
| 381 |
+
global_num_experts,
|
| 382 |
+
expert_map,
|
| 383 |
+
self.w1_scale,
|
| 384 |
+
self.w2_scale,
|
| 385 |
+
a1q_scale,
|
| 386 |
+
a2_scale,
|
| 387 |
+
self.ab_strides1,
|
| 388 |
+
self.ab_strides2,
|
| 389 |
+
self.c_strides1,
|
| 390 |
+
self.c_strides2,
|
| 391 |
+
workspace13,
|
| 392 |
+
workspace2,
|
| 393 |
+
expert_num_tokens,
|
| 394 |
+
self.out_dtype if self.out_dtype is not None else in_dtype,
|
| 395 |
+
self.per_act_token_quant,
|
| 396 |
+
self.per_out_ch_quant,
|
| 397 |
+
use_batched_format,
|
| 398 |
+
topk_weights,
|
| 399 |
+
self._get_permute_scratch(),
|
| 400 |
+
)
|
| 401 |
+
|
| 402 |
+
|
| 403 |
+
class CutlassExpertsFp8(CutlassExpertsFp8Base):
|
| 404 |
+
"""CUTLASS FP8 fused MoE expert implementation."""
|
| 405 |
+
|
| 406 |
+
@staticmethod
|
| 407 |
+
def activation_format() -> mk.FusedMoEActivationFormat:
|
| 408 |
+
return mk.FusedMoEActivationFormat.Standard
|
| 409 |
+
|
| 410 |
+
@staticmethod
|
| 411 |
+
def _supports_parallel_config(moe_parallel_config: FusedMoEParallelConfig) -> bool:
|
| 412 |
+
# CutlassExpertsFp8 does not support expert map, which is
|
| 413 |
+
# needed for STANDARD activation format kernels in DP/EP mode.
|
| 414 |
+
# Note that the BATCHED activation format does not use
|
| 415 |
+
# the expert map for identifying experts.
|
| 416 |
+
return not (
|
| 417 |
+
moe_parallel_config.use_fi_nvl_two_sided_kernels
|
| 418 |
+
or moe_parallel_config.use_deepep_ht_kernels
|
| 419 |
+
or moe_parallel_config.use_fi_nvl_one_sided_kernels
|
| 420 |
+
)
|
| 421 |
+
|
| 422 |
+
def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
|
| 423 |
+
# topk weights and reduction are fused in moe_unpermute cuda kernel
|
| 424 |
+
return TopKWeightAndReduceNoOP()
|
| 425 |
+
|
| 426 |
+
def workspace_dtype(self, act_dtype: torch.dtype) -> torch.dtype:
|
| 427 |
+
return self.out_dtype if self.out_dtype is not None else act_dtype
|
| 428 |
+
|
| 429 |
+
def workspace_shapes(
|
| 430 |
+
self,
|
| 431 |
+
M: int,
|
| 432 |
+
N: int,
|
| 433 |
+
K: int,
|
| 434 |
+
topk: int,
|
| 435 |
+
global_num_experts: int,
|
| 436 |
+
local_num_experts: int,
|
| 437 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 438 |
+
activation: MoEActivation,
|
| 439 |
+
) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
|
| 440 |
+
activation_out_dim = self.adjust_N_for_activation(N, activation)
|
| 441 |
+
workspace1 = (M * topk, max(N, K))
|
| 442 |
+
workspace2 = (M * topk, max(activation_out_dim, K))
|
| 443 |
+
output = (M, K)
|
| 444 |
+
return (workspace1, workspace2, output)
|
| 445 |
+
|
| 446 |
+
|
| 447 |
+
class CutlassBatchedExpertsFp8(CutlassExpertsFp8Base):
|
| 448 |
+
"""Batched CUTLASS FP8 fused MoE expert implementation."""
|
| 449 |
+
|
| 450 |
+
@staticmethod
|
| 451 |
+
def _supports_parallel_config(moe_parallel_config: FusedMoEParallelConfig) -> bool:
|
| 452 |
+
# BATCHED activation format works with EP because
|
| 453 |
+
# expert_map is not used to identify experts (the
|
| 454 |
+
# info is encoded/managed by the P/F logic).
|
| 455 |
+
return True
|
| 456 |
+
|
| 457 |
+
@staticmethod
|
| 458 |
+
def activation_format() -> mk.FusedMoEActivationFormat:
|
| 459 |
+
return mk.FusedMoEActivationFormat.BatchedExperts
|
| 460 |
+
|
| 461 |
+
def workspace_dtype(self, act_dtype: torch.dtype) -> torch.dtype:
|
| 462 |
+
return self.out_dtype if self.out_dtype is not None else act_dtype
|
| 463 |
+
|
| 464 |
+
def workspace_shapes(
|
| 465 |
+
self,
|
| 466 |
+
M: int,
|
| 467 |
+
N: int,
|
| 468 |
+
K: int,
|
| 469 |
+
topk: int,
|
| 470 |
+
global_num_experts: int,
|
| 471 |
+
local_num_experts: int,
|
| 472 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 473 |
+
activation: MoEActivation,
|
| 474 |
+
) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
|
| 475 |
+
num_dp = self.num_dispatchers
|
| 476 |
+
assert num_dp is not None
|
| 477 |
+
experts_per_worker = self.moe_config.num_local_experts
|
| 478 |
+
activation_out_dim = self.adjust_N_for_activation(N, activation)
|
| 479 |
+
workspace1 = (experts_per_worker, M * num_dp, max(N, K))
|
| 480 |
+
workspace2 = (
|
| 481 |
+
experts_per_worker,
|
| 482 |
+
M * num_dp,
|
| 483 |
+
max(activation_out_dim, K),
|
| 484 |
+
)
|
| 485 |
+
output = (experts_per_worker, M, K)
|
| 486 |
+
return (workspace1, workspace2, output)
|
| 487 |
+
|
| 488 |
+
|
| 489 |
+
FLOAT4_E2M1_MAX = scalar_types.float4_e2m1f.max()
|
| 490 |
+
FLOAT8_E4M3_MAX = torch.finfo(torch.float8_e4m3fn).max
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
def run_cutlass_moe_fp4(
|
| 494 |
+
output: torch.Tensor,
|
| 495 |
+
a: torch.Tensor,
|
| 496 |
+
a1_gscale: torch.Tensor,
|
| 497 |
+
w1_fp4: torch.Tensor,
|
| 498 |
+
w1_blockscale: torch.Tensor,
|
| 499 |
+
w1_alphas: torch.Tensor,
|
| 500 |
+
a2_gscale: torch.Tensor,
|
| 501 |
+
w2_fp4: torch.Tensor,
|
| 502 |
+
w2_blockscale: torch.Tensor,
|
| 503 |
+
w2_alphas: torch.Tensor,
|
| 504 |
+
topk_weights: torch.Tensor,
|
| 505 |
+
topk_ids: torch.Tensor,
|
| 506 |
+
activation: MoEActivation,
|
| 507 |
+
workspace13: torch.Tensor,
|
| 508 |
+
workspace2: torch.Tensor,
|
| 509 |
+
m: int,
|
| 510 |
+
n: int,
|
| 511 |
+
k: int,
|
| 512 |
+
e: int,
|
| 513 |
+
device: torch.device,
|
| 514 |
+
apply_router_weight_on_input: bool = False,
|
| 515 |
+
) -> None:
|
| 516 |
+
"""
|
| 517 |
+
MoE implementation for FP4 Inputs
|
| 518 |
+
|
| 519 |
+
# Gemm 1
|
| 520 |
+
a: Input tensor: [m, k] (half/bfloat16)
|
| 521 |
+
a1_gscale: Activation scale per expert: [e] (float32)
|
| 522 |
+
w1 (not an argument to cutlass_moe_fp4): [e, w1_n, k]
|
| 523 |
+
w1_fp4: [e, w1_n, k // 2], dtype: torch.uint8 (stacked fp4: E2M1)
|
| 524 |
+
where w1_n = 2*n for gated activations (gate+up), n for non-gated (up only).
|
| 525 |
+
(Note: `n` is the up projection output dim, `k` is the input dim in
|
| 526 |
+
full precision)
|
| 527 |
+
w1_blockscale: [e, w1_n, k // block_size] (float8_e4m3)
|
| 528 |
+
(Block size = 16 for NVFP4)
|
| 529 |
+
|
| 530 |
+
# Gemm 2
|
| 531 |
+
a2_gscale: Activation scale per expert: [e]
|
| 532 |
+
w2(down projection) (not an argument to cutlass_moe_fp4): [e, k, n]
|
| 533 |
+
w2_fp4: [e, k, n // 2], dtype: torch.uint8 (stacked E2M1)
|
| 534 |
+
w2_blockscale: [e, k, n // block_size], dtype: float8_e4m3
|
| 535 |
+
|
| 536 |
+
topk_weights: [m, topk] dtype: float8
|
| 537 |
+
topk_ids: [m, topk] dtype: float8
|
| 538 |
+
|
| 539 |
+
m, n, k: Unquantized weight shapes, dtype: int
|
| 540 |
+
e: number of experts, dtype: int
|
| 541 |
+
|
| 542 |
+
assumes that topk < k < n to satisfy - up/down projection expectations.
|
| 543 |
+
"""
|
| 544 |
+
is_gated = activation.is_gated
|
| 545 |
+
# For gated activations (e.g. SiLU), w1 output is 2*n (gate + up).
|
| 546 |
+
# For non-gated activations (e.g. SiLU_NO_MUL), w1 output is n (up only).
|
| 547 |
+
w1_n = n * 2 if is_gated else n
|
| 548 |
+
|
| 549 |
+
assert topk_weights.shape == topk_ids.shape, "topk shape mismatch"
|
| 550 |
+
assert w1_fp4.dtype == torch.uint8, "weight 1 must be uint8"
|
| 551 |
+
assert w2_fp4.dtype == torch.uint8, "weight 2 must be uint8"
|
| 552 |
+
assert (
|
| 553 |
+
w1_fp4.ndim == 3
|
| 554 |
+
and w2_fp4.ndim == 3
|
| 555 |
+
and w1_blockscale.ndim == 3
|
| 556 |
+
and w2_blockscale.ndim == 3
|
| 557 |
+
), "All Weights must be of rank 3 for cutlass_moe_fp4"
|
| 558 |
+
m_a, k_a = a.shape
|
| 559 |
+
e_w1, w1_n_actual, half_k_w1 = w1_fp4.shape
|
| 560 |
+
e_w2, k_w2, half_n_w2 = w2_fp4.shape
|
| 561 |
+
|
| 562 |
+
assert e_w1 == e_w2 and e_w1 == e, (
|
| 563 |
+
"Number of experts must match",
|
| 564 |
+
f" between weights. {e_w1}, {e_w2}, {e}",
|
| 565 |
+
)
|
| 566 |
+
assert k_a == half_k_w1 * 2 and k == k_w2, (
|
| 567 |
+
"Hidden size mismatch between a, w1 and w2"
|
| 568 |
+
)
|
| 569 |
+
assert w1_n_actual == w1_n and half_n_w2 * 2 == n, "mismatch in expected `n`"
|
| 570 |
+
assert m == m_a, "input shape mismatch"
|
| 571 |
+
assert 2 * half_k_w1 == k_w2, "Hidden size mismatch w2 and w1"
|
| 572 |
+
assert a.dtype in [torch.half, torch.bfloat16], "Invalid input dtype"
|
| 573 |
+
assert topk_weights.size(0) == m and topk_ids.size(0) == m, (
|
| 574 |
+
"topk must be provided for each row of a"
|
| 575 |
+
)
|
| 576 |
+
topk = topk_ids.size(1)
|
| 577 |
+
out_dtype = a.dtype
|
| 578 |
+
num_topk = topk_ids.size(1)
|
| 579 |
+
|
| 580 |
+
expert_offsets = torch.empty((e + 1), dtype=torch.int32, device=device)
|
| 581 |
+
blockscale_offsets = torch.empty((e + 1), dtype=torch.int32, device=device)
|
| 582 |
+
# Problem size: (num_experts, (m,2n,k))
|
| 583 |
+
problem_sizes1 = torch.empty((e, 3), dtype=torch.int32, device=device)
|
| 584 |
+
# Problem size: (num_experts, (m,n,k))
|
| 585 |
+
problem_sizes2 = torch.empty((e, 3), dtype=torch.int32, device=device)
|
| 586 |
+
|
| 587 |
+
a_map = torch.empty((topk_ids.numel()), dtype=torch.int32, device=device)
|
| 588 |
+
c_map = torch.empty((topk_ids.numel()), dtype=torch.int32, device=device)
|
| 589 |
+
|
| 590 |
+
if apply_router_weight_on_input:
|
| 591 |
+
# TODO: this only works for topK=1, will need to update for topK>1
|
| 592 |
+
assert num_topk == 1, (
|
| 593 |
+
"apply_router_weight_on_input is only implemented for topk=1"
|
| 594 |
+
)
|
| 595 |
+
a.mul_(topk_weights.to(out_dtype))
|
| 596 |
+
|
| 597 |
+
# problem shapes should have [m, n, k]
|
| 598 |
+
# Note that problem sizes are based on logical number of elements.
|
| 599 |
+
ops.get_cutlass_moe_mm_data(
|
| 600 |
+
topk_ids,
|
| 601 |
+
expert_offsets,
|
| 602 |
+
problem_sizes1,
|
| 603 |
+
problem_sizes2,
|
| 604 |
+
a_map,
|
| 605 |
+
c_map,
|
| 606 |
+
e,
|
| 607 |
+
n,
|
| 608 |
+
k,
|
| 609 |
+
blockscale_offsets,
|
| 610 |
+
is_gated=is_gated,
|
| 611 |
+
)
|
| 612 |
+
|
| 613 |
+
a = ops.shuffle_rows(a, a_map)
|
| 614 |
+
rep_a_fp4, rep_a_blockscale = ops.scaled_fp4_experts_quant(
|
| 615 |
+
a,
|
| 616 |
+
a1_gscale,
|
| 617 |
+
expert_offsets,
|
| 618 |
+
blockscale_offsets,
|
| 619 |
+
num_topk,
|
| 620 |
+
)
|
| 621 |
+
c1 = _resize_cache(workspace13, (m * topk, w1_n))
|
| 622 |
+
c2 = _resize_cache(workspace2, (m * topk, n))
|
| 623 |
+
c3 = _resize_cache(workspace13, (m * topk, k))
|
| 624 |
+
ops.cutlass_fp4_moe_mm(
|
| 625 |
+
c1,
|
| 626 |
+
rep_a_fp4,
|
| 627 |
+
w1_fp4,
|
| 628 |
+
rep_a_blockscale,
|
| 629 |
+
w1_blockscale,
|
| 630 |
+
w1_alphas,
|
| 631 |
+
problem_sizes1,
|
| 632 |
+
expert_offsets[:-1],
|
| 633 |
+
blockscale_offsets[:-1],
|
| 634 |
+
)
|
| 635 |
+
del rep_a_fp4, rep_a_blockscale
|
| 636 |
+
if activation == MoEActivation.SILU:
|
| 637 |
+
# Fused SiLU+Mul+NVFP4 quantization
|
| 638 |
+
# Note: c2 workspace is no longer needed since SiLU is fused with quantization.
|
| 639 |
+
# c3 reuses workspace13 after c1 is consumed.
|
| 640 |
+
int_fp4, int_blockscale = ops.silu_and_mul_scaled_fp4_experts_quant(
|
| 641 |
+
c1, a2_gscale, expert_offsets, blockscale_offsets, num_topk
|
| 642 |
+
)
|
| 643 |
+
else:
|
| 644 |
+
apply_moe_activation(activation, c2, c1)
|
| 645 |
+
int_fp4, int_blockscale = ops.scaled_fp4_experts_quant(
|
| 646 |
+
c2, a2_gscale, expert_offsets, blockscale_offsets, num_topk
|
| 647 |
+
)
|
| 648 |
+
|
| 649 |
+
ops.cutlass_fp4_moe_mm(
|
| 650 |
+
c3,
|
| 651 |
+
int_fp4,
|
| 652 |
+
w2_fp4,
|
| 653 |
+
int_blockscale,
|
| 654 |
+
w2_blockscale,
|
| 655 |
+
w2_alphas,
|
| 656 |
+
problem_sizes2,
|
| 657 |
+
expert_offsets[:-1],
|
| 658 |
+
blockscale_offsets[:-1],
|
| 659 |
+
)
|
| 660 |
+
del int_fp4, int_blockscale
|
| 661 |
+
|
| 662 |
+
c3 = ops.shuffle_rows(c3, c_map)
|
| 663 |
+
|
| 664 |
+
assert output.dtype == out_dtype
|
| 665 |
+
if not apply_router_weight_on_input:
|
| 666 |
+
output.copy_(
|
| 667 |
+
(
|
| 668 |
+
c3.view(m, num_topk, k)
|
| 669 |
+
* topk_weights.view(m, num_topk, 1).to(out_dtype)
|
| 670 |
+
).sum(dim=1),
|
| 671 |
+
non_blocking=True,
|
| 672 |
+
)
|
| 673 |
+
else:
|
| 674 |
+
output.copy_(c3.view(m, num_topk, k).sum(dim=1), non_blocking=True)
|
| 675 |
+
return
|
| 676 |
+
|
| 677 |
+
|
| 678 |
+
class CutlassExpertsFp4(mk.FusedMoEExpertsModular):
|
| 679 |
+
"""CUTLASS FP4 fused MoE expert implementation."""
|
| 680 |
+
|
| 681 |
+
def process_weights_after_loading(self, layer: torch.nn.Module) -> None:
|
| 682 |
+
# Fuse activation scales into w_scale_2 in-place so that
|
| 683 |
+
# g1/g2_alphas (which reference the same tensor) stay in sync
|
| 684 |
+
# when EPLB rearranges the parameter.
|
| 685 |
+
layer.w13_weight_scale_2.data.mul_(layer.w13_input_scale)
|
| 686 |
+
layer.w2_weight_scale_2.data.mul_(layer.w2_input_scale)
|
| 687 |
+
|
| 688 |
+
@property
|
| 689 |
+
def expects_unquantized_inputs(self) -> bool:
|
| 690 |
+
return True
|
| 691 |
+
|
| 692 |
+
@staticmethod
|
| 693 |
+
def _supports_current_device() -> bool:
|
| 694 |
+
p = current_platform
|
| 695 |
+
return p.is_cuda() and (
|
| 696 |
+
p.is_device_capability_family(100)
|
| 697 |
+
or p.is_device_capability_family(110)
|
| 698 |
+
or p.is_device_capability_family(120)
|
| 699 |
+
)
|
| 700 |
+
|
| 701 |
+
@staticmethod
|
| 702 |
+
def _supports_no_act_and_mul() -> bool:
|
| 703 |
+
return True
|
| 704 |
+
|
| 705 |
+
@staticmethod
|
| 706 |
+
def _supports_quant_scheme(
|
| 707 |
+
weight_key: QuantKey | None,
|
| 708 |
+
activation_key: QuantKey | None,
|
| 709 |
+
) -> bool:
|
| 710 |
+
return (weight_key, activation_key) == (kNvfp4Static, kNvfp4Dynamic)
|
| 711 |
+
|
| 712 |
+
@staticmethod
|
| 713 |
+
def _supports_activation(activation: MoEActivation) -> bool:
|
| 714 |
+
# SILU uses a fused silu+mul+fp4_quant kernel path.
|
| 715 |
+
# Other gated activations use the generic apply_moe_activation()
|
| 716 |
+
# fallback + separate fp4 quantization in run_cutlass_moe_fp4().
|
| 717 |
+
# Non-gated activations (_NO_MUL) are also supported for models
|
| 718 |
+
# like Nemotron-Nano that don't use gated MLP.
|
| 719 |
+
return activation in [
|
| 720 |
+
MoEActivation.SILU,
|
| 721 |
+
MoEActivation.GELU,
|
| 722 |
+
MoEActivation.GELU_TANH,
|
| 723 |
+
MoEActivation.SWIGLUOAI,
|
| 724 |
+
MoEActivation.SWIGLUSTEP,
|
| 725 |
+
MoEActivation.SILU_NO_MUL,
|
| 726 |
+
MoEActivation.GELU_NO_MUL,
|
| 727 |
+
MoEActivation.GELU_TANH_NO_MUL,
|
| 728 |
+
MoEActivation.RELU2_NO_MUL,
|
| 729 |
+
]
|
| 730 |
+
|
| 731 |
+
@staticmethod
|
| 732 |
+
def _supports_parallel_config(moe_parallel_config: FusedMoEParallelConfig) -> bool:
|
| 733 |
+
# CutlassExpertsFp4 does not support expert map, which is
|
| 734 |
+
# needed for STANDARD activation format kernels in EP mode.
|
| 735 |
+
return moe_parallel_config.ep_size == 1
|
| 736 |
+
|
| 737 |
+
@staticmethod
|
| 738 |
+
def activation_format() -> mk.FusedMoEActivationFormat:
|
| 739 |
+
return mk.FusedMoEActivationFormat.Standard
|
| 740 |
+
|
| 741 |
+
def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
|
| 742 |
+
return TopKWeightAndReduceNoOP()
|
| 743 |
+
|
| 744 |
+
def workspace_dtype(self, act_dtype: torch.dtype) -> torch.dtype:
|
| 745 |
+
return act_dtype
|
| 746 |
+
|
| 747 |
+
def workspace_shapes(
|
| 748 |
+
self,
|
| 749 |
+
M: int,
|
| 750 |
+
N: int,
|
| 751 |
+
K: int,
|
| 752 |
+
topk: int,
|
| 753 |
+
global_num_experts: int,
|
| 754 |
+
local_num_experts: int,
|
| 755 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 756 |
+
activation: MoEActivation,
|
| 757 |
+
) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
|
| 758 |
+
workspace1 = (M * topk, max(2 * N, K))
|
| 759 |
+
workspace2 = (M * topk, N)
|
| 760 |
+
output = (M, K)
|
| 761 |
+
return (workspace1, workspace2, output)
|
| 762 |
+
|
| 763 |
+
def apply(
|
| 764 |
+
self,
|
| 765 |
+
output: torch.Tensor,
|
| 766 |
+
hidden_states: torch.Tensor,
|
| 767 |
+
w1: torch.Tensor,
|
| 768 |
+
w2: torch.Tensor,
|
| 769 |
+
topk_weights: torch.Tensor,
|
| 770 |
+
topk_ids: torch.Tensor,
|
| 771 |
+
activation: MoEActivation,
|
| 772 |
+
global_num_experts: int,
|
| 773 |
+
expert_map: torch.Tensor | None,
|
| 774 |
+
a1q_scale: torch.Tensor | None, # unused
|
| 775 |
+
a2_scale: torch.Tensor | None, # unused
|
| 776 |
+
workspace13: torch.Tensor | None,
|
| 777 |
+
workspace2: torch.Tensor | None,
|
| 778 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 779 |
+
apply_router_weight_on_input: bool,
|
| 780 |
+
):
|
| 781 |
+
e, m, n, k, _ = self.moe_problem_size(hidden_states, w1, w2, topk_ids)
|
| 782 |
+
n = w2.shape[2] * 2
|
| 783 |
+
|
| 784 |
+
run_cutlass_moe_fp4(
|
| 785 |
+
output=output,
|
| 786 |
+
a=hidden_states,
|
| 787 |
+
a1_gscale=self.a1_gscale,
|
| 788 |
+
w1_fp4=w1,
|
| 789 |
+
w1_blockscale=self.w1_scale,
|
| 790 |
+
w1_alphas=self.g1_alphas,
|
| 791 |
+
a2_gscale=self.a2_gscale,
|
| 792 |
+
w2_fp4=w2,
|
| 793 |
+
w2_blockscale=self.w2_scale,
|
| 794 |
+
w2_alphas=self.g2_alphas,
|
| 795 |
+
topk_weights=topk_weights,
|
| 796 |
+
topk_ids=topk_ids,
|
| 797 |
+
activation=activation,
|
| 798 |
+
workspace13=workspace13,
|
| 799 |
+
workspace2=workspace2,
|
| 800 |
+
m=m,
|
| 801 |
+
n=n,
|
| 802 |
+
k=k,
|
| 803 |
+
e=e,
|
| 804 |
+
device=hidden_states.device,
|
| 805 |
+
apply_router_weight_on_input=apply_router_weight_on_input,
|
| 806 |
+
)
|
| 807 |
+
|
| 808 |
+
|
| 809 |
+
def run_cutlass_moe_mxfp4(
|
| 810 |
+
output: torch.Tensor,
|
| 811 |
+
a: torch.Tensor,
|
| 812 |
+
w1_fp4: torch.Tensor,
|
| 813 |
+
w1_blockscale: torch.Tensor,
|
| 814 |
+
w2_fp4: torch.Tensor,
|
| 815 |
+
w2_blockscale: torch.Tensor,
|
| 816 |
+
topk_weights: torch.Tensor,
|
| 817 |
+
topk_ids: torch.Tensor,
|
| 818 |
+
activation: MoEActivation,
|
| 819 |
+
workspace13: torch.Tensor,
|
| 820 |
+
workspace2: torch.Tensor,
|
| 821 |
+
m: int,
|
| 822 |
+
n: int,
|
| 823 |
+
k: int,
|
| 824 |
+
e: int,
|
| 825 |
+
device: torch.device,
|
| 826 |
+
apply_router_weight_on_input: bool = False,
|
| 827 |
+
swiglu_limit: float | None = None,
|
| 828 |
+
) -> None:
|
| 829 |
+
"""MXFP4 x MXFP4 MoE implementation using CUTLASS grouped GEMM."""
|
| 830 |
+
is_gated = activation.is_gated
|
| 831 |
+
w1_n = n * 2 if is_gated else n
|
| 832 |
+
|
| 833 |
+
assert topk_weights.shape == topk_ids.shape, "topk shape mismatch"
|
| 834 |
+
assert w1_fp4.dtype == torch.uint8, "weight 1 must be uint8"
|
| 835 |
+
assert w2_fp4.dtype == torch.uint8, "weight 2 must be uint8"
|
| 836 |
+
assert (
|
| 837 |
+
w1_fp4.ndim == 3
|
| 838 |
+
and w2_fp4.ndim == 3
|
| 839 |
+
and w1_blockscale.ndim == 3
|
| 840 |
+
and w2_blockscale.ndim == 3
|
| 841 |
+
), "All Weights must be of rank 3 for cutlass_moe_mxfp4"
|
| 842 |
+
m_a, k_a = a.shape
|
| 843 |
+
e_w1, w1_n_actual, half_k_w1 = w1_fp4.shape
|
| 844 |
+
e_w2, k_w2, half_n_w2 = w2_fp4.shape
|
| 845 |
+
|
| 846 |
+
assert e_w1 == e_w2 and e_w1 == e
|
| 847 |
+
assert k_a == half_k_w1 * 2 and k == k_w2
|
| 848 |
+
assert w1_n_actual == w1_n and half_n_w2 * 2 == n
|
| 849 |
+
assert m == m_a
|
| 850 |
+
assert 2 * half_k_w1 == k_w2
|
| 851 |
+
assert a.dtype in [torch.half, torch.bfloat16], "Invalid input dtype"
|
| 852 |
+
assert topk_weights.size(0) == m and topk_ids.size(0) == m
|
| 853 |
+
|
| 854 |
+
topk = topk_ids.size(1)
|
| 855 |
+
out_dtype = a.dtype
|
| 856 |
+
num_topk = topk_ids.size(1)
|
| 857 |
+
|
| 858 |
+
expert_offsets = torch.empty((e + 1), dtype=torch.int32, device=device)
|
| 859 |
+
blockscale_offsets = torch.empty((e + 1), dtype=torch.int32, device=device)
|
| 860 |
+
problem_sizes1 = torch.empty((e, 3), dtype=torch.int32, device=device)
|
| 861 |
+
problem_sizes2 = torch.empty((e, 3), dtype=torch.int32, device=device)
|
| 862 |
+
|
| 863 |
+
a_map = torch.empty((topk_ids.numel()), dtype=torch.int32, device=device)
|
| 864 |
+
c_map = torch.empty((topk_ids.numel()), dtype=torch.int32, device=device)
|
| 865 |
+
|
| 866 |
+
if apply_router_weight_on_input:
|
| 867 |
+
assert num_topk == 1, (
|
| 868 |
+
"apply_router_weight_on_input is only implemented for topk=1"
|
| 869 |
+
)
|
| 870 |
+
a.mul_(topk_weights.to(out_dtype))
|
| 871 |
+
|
| 872 |
+
ops.get_cutlass_moe_mm_data(
|
| 873 |
+
topk_ids,
|
| 874 |
+
expert_offsets,
|
| 875 |
+
problem_sizes1,
|
| 876 |
+
problem_sizes2,
|
| 877 |
+
a_map,
|
| 878 |
+
c_map,
|
| 879 |
+
e,
|
| 880 |
+
n,
|
| 881 |
+
k,
|
| 882 |
+
blockscale_offsets,
|
| 883 |
+
is_gated=is_gated,
|
| 884 |
+
)
|
| 885 |
+
|
| 886 |
+
a = ops.shuffle_rows(a, a_map)
|
| 887 |
+
rep_a_fp4, rep_a_blockscale = ops.mxfp4_experts_quant(
|
| 888 |
+
a,
|
| 889 |
+
expert_offsets,
|
| 890 |
+
blockscale_offsets,
|
| 891 |
+
e,
|
| 892 |
+
num_topk,
|
| 893 |
+
)
|
| 894 |
+
c1 = _resize_cache(workspace13, (m * topk, w1_n))
|
| 895 |
+
c2 = _resize_cache(workspace2, (m * topk, n))
|
| 896 |
+
c3 = _resize_cache(workspace13, (m * topk, k))
|
| 897 |
+
|
| 898 |
+
ops.cutlass_mxfp4_moe_mm(
|
| 899 |
+
c1,
|
| 900 |
+
rep_a_fp4,
|
| 901 |
+
w1_fp4,
|
| 902 |
+
rep_a_blockscale,
|
| 903 |
+
w1_blockscale,
|
| 904 |
+
problem_sizes1,
|
| 905 |
+
expert_offsets[:-1],
|
| 906 |
+
blockscale_offsets[:-1],
|
| 907 |
+
)
|
| 908 |
+
del rep_a_fp4, rep_a_blockscale
|
| 909 |
+
if activation == MoEActivation.SILU and swiglu_limit is None:
|
| 910 |
+
# Fused silu+mul+requantize; no clamp variant exists, so a layer that
|
| 911 |
+
# declares a SwiGLU limit has to take the generic path below.
|
| 912 |
+
int_fp4, int_blockscale = ops.silu_and_mul_mxfp4_experts_quant(
|
| 913 |
+
c1, expert_offsets, blockscale_offsets, e, num_topk
|
| 914 |
+
)
|
| 915 |
+
else:
|
| 916 |
+
apply_moe_activation(activation, c2, c1, clamp_limit=swiglu_limit)
|
| 917 |
+
int_fp4, int_blockscale = ops.mxfp4_experts_quant(
|
| 918 |
+
c2, expert_offsets, blockscale_offsets, e, num_topk
|
| 919 |
+
)
|
| 920 |
+
|
| 921 |
+
ops.cutlass_mxfp4_moe_mm(
|
| 922 |
+
c3,
|
| 923 |
+
int_fp4,
|
| 924 |
+
w2_fp4,
|
| 925 |
+
int_blockscale,
|
| 926 |
+
w2_blockscale,
|
| 927 |
+
problem_sizes2,
|
| 928 |
+
expert_offsets[:-1],
|
| 929 |
+
blockscale_offsets[:-1],
|
| 930 |
+
)
|
| 931 |
+
del int_fp4, int_blockscale
|
| 932 |
+
|
| 933 |
+
c3 = ops.shuffle_rows(c3, c_map)
|
| 934 |
+
|
| 935 |
+
assert output.dtype == out_dtype
|
| 936 |
+
if not apply_router_weight_on_input:
|
| 937 |
+
output.copy_(
|
| 938 |
+
(
|
| 939 |
+
c3.view(m, num_topk, k)
|
| 940 |
+
* topk_weights.view(m, num_topk, 1).to(out_dtype)
|
| 941 |
+
).sum(dim=1),
|
| 942 |
+
non_blocking=True,
|
| 943 |
+
)
|
| 944 |
+
else:
|
| 945 |
+
output.copy_(c3.view(m, num_topk, k).sum(dim=1), non_blocking=True)
|
| 946 |
+
return
|
| 947 |
+
|
| 948 |
+
|
| 949 |
+
def swizzle_mxfp4_scales(
|
| 950 |
+
scales: torch.Tensor,
|
| 951 |
+
N: int,
|
| 952 |
+
K: int,
|
| 953 |
+
) -> torch.Tensor:
|
| 954 |
+
"""Swizzle flat [N, K//32] E8M0 scales to CUTLASS tiled layout.
|
| 955 |
+
|
| 956 |
+
CUTLASS expects MX scale factors in a tiled layout:
|
| 957 |
+
[numMTiles, numKTiles, 32, 4, 4]
|
| 958 |
+
where numMTiles = ceil(N/128), numKTiles = ceil(K/128),
|
| 959 |
+
and the inner dimensions correspond to the swizzle pattern:
|
| 960 |
+
mTileIdx = mIdx / 128
|
| 961 |
+
outerMIdx = mIdx % 32
|
| 962 |
+
innerMIdx = (mIdx / 32) % 4
|
| 963 |
+
kTileIdx = kIdx / 4
|
| 964 |
+
innerKIdx = kIdx % 4
|
| 965 |
+
with kIdx = col_in_scale_space (i.e., index into K//32).
|
| 966 |
+
"""
|
| 967 |
+
assert scales.dtype == torch.uint8
|
| 968 |
+
num_scale_cols = K // 32 # number of E8M0 scale values per row
|
| 969 |
+
|
| 970 |
+
num_m_tiles = (N + 127) // 128
|
| 971 |
+
num_k_tiles = (num_scale_cols + 3) // 4
|
| 972 |
+
|
| 973 |
+
# Pad N to multiple of 128 and scale_cols to multiple of 4
|
| 974 |
+
padded_N = num_m_tiles * 128
|
| 975 |
+
padded_scale_cols = num_k_tiles * 4
|
| 976 |
+
|
| 977 |
+
# Start with flat scales, pad if needed
|
| 978 |
+
padded = torch.zeros(
|
| 979 |
+
padded_N, padded_scale_cols, dtype=torch.uint8, device=scales.device
|
| 980 |
+
)
|
| 981 |
+
padded[:N, :num_scale_cols] = scales
|
| 982 |
+
|
| 983 |
+
# Reshape to tile structure:
|
| 984 |
+
# [numMTiles, 4, 32, numKTiles, 4]
|
| 985 |
+
# mTileIdx, innerMIdx, outerMIdx, kTileIdx, innerKIdx
|
| 986 |
+
tiled = padded.reshape(num_m_tiles, 4, 32, num_k_tiles, 4)
|
| 987 |
+
# Permute to [numMTiles, numKTiles, 32, 4, 4]
|
| 988 |
+
# (outerMIdx, innerMIdx, innerKIdx)
|
| 989 |
+
tiled = tiled.permute(0, 3, 2, 1, 4).contiguous()
|
| 990 |
+
return tiled.reshape(-1)
|
| 991 |
+
|
| 992 |
+
|
| 993 |
+
class CutlassExpertsMxfp4(mk.FusedMoEExpertsModular):
|
| 994 |
+
"""CUTLASS MXFP4 x MXFP4 fused MoE expert implementation."""
|
| 995 |
+
|
| 996 |
+
@property
|
| 997 |
+
def expects_unquantized_inputs(self) -> bool:
|
| 998 |
+
return True
|
| 999 |
+
|
| 1000 |
+
@staticmethod
|
| 1001 |
+
def _supports_current_device() -> bool:
|
| 1002 |
+
p = current_platform
|
| 1003 |
+
capability = p.get_device_capability()
|
| 1004 |
+
return (
|
| 1005 |
+
p.is_cuda()
|
| 1006 |
+
and capability is not None
|
| 1007 |
+
and ops.mxfp4_experts_quant_supported(capability.to_int())
|
| 1008 |
+
)
|
| 1009 |
+
|
| 1010 |
+
@staticmethod
|
| 1011 |
+
def _supports_no_act_and_mul() -> bool:
|
| 1012 |
+
return True
|
| 1013 |
+
|
| 1014 |
+
@staticmethod
|
| 1015 |
+
def _supports_quant_scheme(
|
| 1016 |
+
weight_key: QuantKey | None,
|
| 1017 |
+
activation_key: QuantKey | None,
|
| 1018 |
+
) -> bool:
|
| 1019 |
+
return (weight_key, activation_key) == (kMxfp4Static, kMxfp4Dynamic)
|
| 1020 |
+
|
| 1021 |
+
@staticmethod
|
| 1022 |
+
def _supports_activation(activation: MoEActivation) -> bool:
|
| 1023 |
+
return activation in [
|
| 1024 |
+
MoEActivation.SILU,
|
| 1025 |
+
MoEActivation.GELU,
|
| 1026 |
+
MoEActivation.SWIGLUOAI,
|
| 1027 |
+
MoEActivation.SWIGLUSTEP,
|
| 1028 |
+
MoEActivation.SILU_NO_MUL,
|
| 1029 |
+
MoEActivation.GELU_NO_MUL,
|
| 1030 |
+
MoEActivation.RELU2_NO_MUL,
|
| 1031 |
+
]
|
| 1032 |
+
|
| 1033 |
+
@staticmethod
|
| 1034 |
+
def _supports_parallel_config(
|
| 1035 |
+
moe_parallel_config: FusedMoEParallelConfig,
|
| 1036 |
+
) -> bool:
|
| 1037 |
+
return moe_parallel_config.ep_size == 1
|
| 1038 |
+
|
| 1039 |
+
@staticmethod
|
| 1040 |
+
def activation_format() -> mk.FusedMoEActivationFormat:
|
| 1041 |
+
return mk.FusedMoEActivationFormat.Standard
|
| 1042 |
+
|
| 1043 |
+
def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
|
| 1044 |
+
return TopKWeightAndReduceNoOP()
|
| 1045 |
+
|
| 1046 |
+
def workspace_dtype(self, act_dtype: torch.dtype) -> torch.dtype:
|
| 1047 |
+
return act_dtype
|
| 1048 |
+
|
| 1049 |
+
def workspace_shapes(
|
| 1050 |
+
self,
|
| 1051 |
+
M: int,
|
| 1052 |
+
N: int,
|
| 1053 |
+
K: int,
|
| 1054 |
+
topk: int,
|
| 1055 |
+
global_num_experts: int,
|
| 1056 |
+
local_num_experts: int,
|
| 1057 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 1058 |
+
activation: MoEActivation,
|
| 1059 |
+
) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
|
| 1060 |
+
workspace1 = (M * topk, max(2 * N, K))
|
| 1061 |
+
workspace2 = (M * topk, N)
|
| 1062 |
+
output = (M, K)
|
| 1063 |
+
return (workspace1, workspace2, output)
|
| 1064 |
+
|
| 1065 |
+
def apply(
|
| 1066 |
+
self,
|
| 1067 |
+
output: torch.Tensor,
|
| 1068 |
+
hidden_states: torch.Tensor,
|
| 1069 |
+
w1: torch.Tensor,
|
| 1070 |
+
w2: torch.Tensor,
|
| 1071 |
+
topk_weights: torch.Tensor,
|
| 1072 |
+
topk_ids: torch.Tensor,
|
| 1073 |
+
activation: MoEActivation,
|
| 1074 |
+
global_num_experts: int,
|
| 1075 |
+
expert_map: torch.Tensor | None,
|
| 1076 |
+
a1q_scale: torch.Tensor | None,
|
| 1077 |
+
a2_scale: torch.Tensor | None,
|
| 1078 |
+
workspace13: torch.Tensor | None,
|
| 1079 |
+
workspace2: torch.Tensor | None,
|
| 1080 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 1081 |
+
apply_router_weight_on_input: bool,
|
| 1082 |
+
):
|
| 1083 |
+
e, m, n, k, _ = self.moe_problem_size(hidden_states, w1, w2, topk_ids)
|
| 1084 |
+
n = w2.shape[2] * 2
|
| 1085 |
+
|
| 1086 |
+
run_cutlass_moe_mxfp4(
|
| 1087 |
+
output=output,
|
| 1088 |
+
a=hidden_states,
|
| 1089 |
+
w1_fp4=w1,
|
| 1090 |
+
w1_blockscale=self.w1_scale,
|
| 1091 |
+
w2_fp4=w2,
|
| 1092 |
+
w2_blockscale=self.w2_scale,
|
| 1093 |
+
topk_weights=topk_weights,
|
| 1094 |
+
topk_ids=topk_ids,
|
| 1095 |
+
activation=activation,
|
| 1096 |
+
workspace13=workspace13,
|
| 1097 |
+
workspace2=workspace2,
|
| 1098 |
+
m=m,
|
| 1099 |
+
n=n,
|
| 1100 |
+
k=k,
|
| 1101 |
+
e=e,
|
| 1102 |
+
device=hidden_states.device,
|
| 1103 |
+
apply_router_weight_on_input=apply_router_weight_on_input,
|
| 1104 |
+
swiglu_limit=self.quant_config.gemm1_clamp_limit,
|
| 1105 |
+
)
|
| 1106 |
+
|
| 1107 |
+
|
| 1108 |
+
# W4A8
|
| 1109 |
+
def run_cutlass_moe_w4a8_fp8(
|
| 1110 |
+
output: torch.Tensor,
|
| 1111 |
+
hidden_states: torch.Tensor,
|
| 1112 |
+
w1: torch.Tensor,
|
| 1113 |
+
w2: torch.Tensor,
|
| 1114 |
+
topk_ids: torch.Tensor,
|
| 1115 |
+
activation: MoEActivation,
|
| 1116 |
+
global_num_experts: int,
|
| 1117 |
+
expert_map: torch.Tensor | None,
|
| 1118 |
+
w1_scale: torch.Tensor | None,
|
| 1119 |
+
w2_scale: torch.Tensor | None,
|
| 1120 |
+
a1q_scale: torch.Tensor | None,
|
| 1121 |
+
a2_scale: torch.Tensor | None,
|
| 1122 |
+
w1_chan_scale: torch.Tensor,
|
| 1123 |
+
w2_chan_scale: torch.Tensor,
|
| 1124 |
+
a_strides1: torch.Tensor,
|
| 1125 |
+
a_strides2: torch.Tensor,
|
| 1126 |
+
b_strides1: torch.Tensor,
|
| 1127 |
+
b_strides2: torch.Tensor,
|
| 1128 |
+
c_strides1: torch.Tensor,
|
| 1129 |
+
c_strides2: torch.Tensor,
|
| 1130 |
+
s_strides1: torch.Tensor,
|
| 1131 |
+
s_strides2: torch.Tensor,
|
| 1132 |
+
workspace13: torch.Tensor,
|
| 1133 |
+
workspace2: torch.Tensor,
|
| 1134 |
+
expert_num_tokens: torch.Tensor | None,
|
| 1135 |
+
out_dtype: torch.dtype,
|
| 1136 |
+
per_act_token: bool,
|
| 1137 |
+
per_out_ch: bool,
|
| 1138 |
+
use_batched_format: bool,
|
| 1139 |
+
topk_weights: torch.Tensor | None,
|
| 1140 |
+
group_size: int,
|
| 1141 |
+
permute_scratch: MoEPermuteScratch | None,
|
| 1142 |
+
):
|
| 1143 |
+
a1q = hidden_states
|
| 1144 |
+
M = a1q.size(0)
|
| 1145 |
+
local_E = w1.size(0)
|
| 1146 |
+
device = a1q.device
|
| 1147 |
+
_, K, N_packed = w2.shape
|
| 1148 |
+
N = N_packed * 8 # logical N, pack 8 int4 into 1 int32
|
| 1149 |
+
|
| 1150 |
+
assert per_act_token, "W4A8 must use per-token scales"
|
| 1151 |
+
assert per_out_ch, "W4A8 must use per-channel scales"
|
| 1152 |
+
assert w1_scale is not None
|
| 1153 |
+
assert w2_scale is not None
|
| 1154 |
+
assert w1_scale.dtype == torch.float8_e4m3fn
|
| 1155 |
+
assert w2_scale.dtype == torch.float8_e4m3fn
|
| 1156 |
+
assert w1.dtype == torch.int32
|
| 1157 |
+
assert w2.dtype == torch.int32
|
| 1158 |
+
assert w1_chan_scale.dtype == torch.float32
|
| 1159 |
+
assert w2_chan_scale.dtype == torch.float32
|
| 1160 |
+
assert w1.size(0) == w2.size(0), "Weights expert number mismatch"
|
| 1161 |
+
assert a1q_scale is not None
|
| 1162 |
+
assert a2_scale is None
|
| 1163 |
+
assert out_dtype in [torch.bfloat16], f"Invalid output dtype: {out_dtype}"
|
| 1164 |
+
if expert_map is not None:
|
| 1165 |
+
assert expert_num_tokens is None
|
| 1166 |
+
assert not use_batched_format, "batched format not supported yet"
|
| 1167 |
+
assert group_size == 128, f"Only group size 128 supported but got {group_size=}"
|
| 1168 |
+
|
| 1169 |
+
assert global_num_experts != -1
|
| 1170 |
+
assert w1.size(2) * 8 == K, (
|
| 1171 |
+
f"w1 hidden size mismatch: got {w1.size(2) * 8}, expected {K=}"
|
| 1172 |
+
)
|
| 1173 |
+
|
| 1174 |
+
topk = topk_ids.size(1)
|
| 1175 |
+
a1q_perm = _resize_cache(workspace2.view(dtype=torch.float8_e4m3fn), (M * topk, K))
|
| 1176 |
+
mm1_out = _resize_cache(workspace13, (M * topk, N * 2))
|
| 1177 |
+
act_out = _resize_cache(workspace2, (M * topk, N))
|
| 1178 |
+
# original workspace are based on input hidden_states dtype (bf16)
|
| 1179 |
+
quant_out = _resize_cache(
|
| 1180 |
+
workspace13.view(dtype=torch.float8_e4m3fn), (M * topk, N)
|
| 1181 |
+
)
|
| 1182 |
+
mm2_out = _resize_cache(workspace2, (M * topk, K))
|
| 1183 |
+
|
| 1184 |
+
problem_sizes1 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 1185 |
+
problem_sizes2 = torch.empty((local_E, 3), dtype=torch.int32, device=device)
|
| 1186 |
+
|
| 1187 |
+
num_expert = global_num_experts if expert_map is None else expert_map.size(0)
|
| 1188 |
+
# permuted a1q reuses workspace2
|
| 1189 |
+
a1q, a1q_scale, expert_first_token_offset, inv_perm, _ = moe_permute(
|
| 1190 |
+
a1q,
|
| 1191 |
+
a1q_scale,
|
| 1192 |
+
topk_ids,
|
| 1193 |
+
num_expert,
|
| 1194 |
+
local_E,
|
| 1195 |
+
expert_map,
|
| 1196 |
+
permuted_hidden_states=a1q_perm,
|
| 1197 |
+
scratch=permute_scratch,
|
| 1198 |
+
)
|
| 1199 |
+
# for RS gemm SwapAB is always enabled (swap logical M, N in the problem shape).
|
| 1200 |
+
ops.get_cutlass_moe_mm_problem_sizes_from_expert_offsets(
|
| 1201 |
+
expert_first_token_offset, problem_sizes1, problem_sizes2, N, K, True
|
| 1202 |
+
)
|
| 1203 |
+
expert_offsets = expert_first_token_offset[:-1]
|
| 1204 |
+
|
| 1205 |
+
ops.cutlass_w4a8_moe_mm(
|
| 1206 |
+
mm1_out,
|
| 1207 |
+
a1q,
|
| 1208 |
+
w1,
|
| 1209 |
+
a1q_scale,
|
| 1210 |
+
w1_chan_scale,
|
| 1211 |
+
w1_scale,
|
| 1212 |
+
group_size,
|
| 1213 |
+
expert_offsets,
|
| 1214 |
+
problem_sizes1,
|
| 1215 |
+
a_strides1,
|
| 1216 |
+
b_strides1,
|
| 1217 |
+
c_strides1,
|
| 1218 |
+
s_strides1,
|
| 1219 |
+
)
|
| 1220 |
+
|
| 1221 |
+
apply_moe_activation(activation, act_out, mm1_out)
|
| 1222 |
+
|
| 1223 |
+
a2q, a2q_scale = ops.scaled_fp8_quant(
|
| 1224 |
+
act_out, a2_scale, use_per_token_if_dynamic=per_act_token, output=quant_out
|
| 1225 |
+
)
|
| 1226 |
+
|
| 1227 |
+
ops.cutlass_w4a8_moe_mm(
|
| 1228 |
+
mm2_out,
|
| 1229 |
+
a2q,
|
| 1230 |
+
w2,
|
| 1231 |
+
a2q_scale,
|
| 1232 |
+
w2_chan_scale,
|
| 1233 |
+
w2_scale,
|
| 1234 |
+
group_size,
|
| 1235 |
+
expert_offsets,
|
| 1236 |
+
problem_sizes2,
|
| 1237 |
+
a_strides2,
|
| 1238 |
+
b_strides2,
|
| 1239 |
+
c_strides2,
|
| 1240 |
+
s_strides2,
|
| 1241 |
+
)
|
| 1242 |
+
|
| 1243 |
+
# for non-chunking mode the output is resized from workspace13
|
| 1244 |
+
# so we need to make sure mm2_out uses workspace2.
|
| 1245 |
+
moe_unpermute(
|
| 1246 |
+
out=output,
|
| 1247 |
+
permuted_hidden_states=mm2_out,
|
| 1248 |
+
topk_weights=topk_weights,
|
| 1249 |
+
inv_permuted_idx=inv_perm,
|
| 1250 |
+
expert_first_token_offset=expert_first_token_offset,
|
| 1251 |
+
)
|
| 1252 |
+
|
| 1253 |
+
|
| 1254 |
+
class CutlassExpertsW4A8Fp8(mk.FusedMoEExpertsModular):
|
| 1255 |
+
def __init__(
|
| 1256 |
+
self,
|
| 1257 |
+
moe_config: FusedMoEConfig,
|
| 1258 |
+
quant_config: FusedMoEQuantConfig,
|
| 1259 |
+
b_strides1: torch.Tensor,
|
| 1260 |
+
b_strides2: torch.Tensor,
|
| 1261 |
+
group_size: int,
|
| 1262 |
+
):
|
| 1263 |
+
super().__init__(moe_config=moe_config, quant_config=quant_config)
|
| 1264 |
+
|
| 1265 |
+
e = moe_config.num_local_experts
|
| 1266 |
+
n = moe_config.intermediate_size_per_partition
|
| 1267 |
+
k = moe_config.hidden_dim
|
| 1268 |
+
device = moe_config.device
|
| 1269 |
+
|
| 1270 |
+
self.out_dtype = moe_config.in_dtype
|
| 1271 |
+
|
| 1272 |
+
a_strides1_c_strides2 = torch.full((e,), k, device=device, dtype=torch.int64)
|
| 1273 |
+
self.a_strides1 = a_strides1_c_strides2
|
| 1274 |
+
self.a_strides2 = torch.full((e,), n, device=device, dtype=torch.int64)
|
| 1275 |
+
self.c_strides1 = torch.full((e,), 2 * n, device=device, dtype=torch.int64)
|
| 1276 |
+
self.c_strides2 = a_strides1_c_strides2
|
| 1277 |
+
|
| 1278 |
+
self.b_strides1 = b_strides1
|
| 1279 |
+
self.b_strides2 = b_strides2
|
| 1280 |
+
|
| 1281 |
+
# sizeof(StrideS) = 16 bytes, encoded as 2xint64.
|
| 1282 |
+
self.s_strides1 = torch.zeros((e, 2), device=device, dtype=torch.int64)
|
| 1283 |
+
self.s_strides1[:, 0] = 2 * n
|
| 1284 |
+
self.s_strides2 = torch.zeros((e, 2), device=device, dtype=torch.int64)
|
| 1285 |
+
self.s_strides2[:, 0] = k
|
| 1286 |
+
|
| 1287 |
+
self.group_size = group_size
|
| 1288 |
+
self._permute_scratch: MoEPermuteScratch | None = None
|
| 1289 |
+
|
| 1290 |
+
@staticmethod
|
| 1291 |
+
def activation_format() -> mk.FusedMoEActivationFormat:
|
| 1292 |
+
return mk.FusedMoEActivationFormat.Standard
|
| 1293 |
+
|
| 1294 |
+
@staticmethod
|
| 1295 |
+
def is_supported_config(
|
| 1296 |
+
cls: type[mk.FusedMoEExperts],
|
| 1297 |
+
moe_config: FusedMoEConfig,
|
| 1298 |
+
weight_key: QuantKey | None,
|
| 1299 |
+
activation_key: QuantKey | None,
|
| 1300 |
+
activation_format: mk.FusedMoEActivationFormat,
|
| 1301 |
+
) -> tuple[bool, str | None]:
|
| 1302 |
+
if moe_config.in_dtype != torch.bfloat16:
|
| 1303 |
+
return (
|
| 1304 |
+
False,
|
| 1305 |
+
f"kernel does not support {moe_config.in_dtype} input/output dtype",
|
| 1306 |
+
)
|
| 1307 |
+
|
| 1308 |
+
return mk.FusedMoEExperts.is_supported_config(
|
| 1309 |
+
cls,
|
| 1310 |
+
moe_config,
|
| 1311 |
+
weight_key,
|
| 1312 |
+
activation_key,
|
| 1313 |
+
activation_format,
|
| 1314 |
+
)
|
| 1315 |
+
|
| 1316 |
+
@staticmethod
|
| 1317 |
+
def _supports_current_device() -> bool:
|
| 1318 |
+
return cutlass_group_gemm_supported()
|
| 1319 |
+
|
| 1320 |
+
@staticmethod
|
| 1321 |
+
def _supports_no_act_and_mul() -> bool:
|
| 1322 |
+
return False
|
| 1323 |
+
|
| 1324 |
+
@staticmethod
|
| 1325 |
+
def _supports_quant_scheme(
|
| 1326 |
+
weight_key: QuantKey | None,
|
| 1327 |
+
activation_key: QuantKey | None,
|
| 1328 |
+
) -> bool:
|
| 1329 |
+
return (weight_key, activation_key) == (kInt4Static, kFp8DynamicTokenSym)
|
| 1330 |
+
|
| 1331 |
+
@staticmethod
|
| 1332 |
+
def _supports_activation(activation: MoEActivation) -> bool:
|
| 1333 |
+
return activation in (
|
| 1334 |
+
MoEActivation.SILU,
|
| 1335 |
+
MoEActivation.GELU,
|
| 1336 |
+
MoEActivation.SWIGLUOAI,
|
| 1337 |
+
)
|
| 1338 |
+
|
| 1339 |
+
@staticmethod
|
| 1340 |
+
def _supports_parallel_config(moe_parallel_config: FusedMoEParallelConfig) -> bool:
|
| 1341 |
+
return True
|
| 1342 |
+
|
| 1343 |
+
def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
|
| 1344 |
+
# topk weights and reduction are fused in moe_unpermute cuda kernel
|
| 1345 |
+
return TopKWeightAndReduceNoOP()
|
| 1346 |
+
|
| 1347 |
+
def workspace_dtype(self, act_dtype: torch.dtype) -> torch.dtype:
|
| 1348 |
+
return self.out_dtype if self.out_dtype is not None else act_dtype
|
| 1349 |
+
|
| 1350 |
+
def _get_permute_scratch(self) -> MoEPermuteScratch | None:
|
| 1351 |
+
if self._permute_scratch is None and moe_permute_unpermute_supported():
|
| 1352 |
+
self._permute_scratch = MoEPermuteScratch(
|
| 1353 |
+
max_num_tokens=self.moe_config.max_num_tokens,
|
| 1354 |
+
topk=self.moe_config.experts_per_token,
|
| 1355 |
+
num_experts=self.moe_config.num_experts,
|
| 1356 |
+
num_local_experts=self.moe_config.num_local_experts,
|
| 1357 |
+
device=torch.device(self.moe_config.device),
|
| 1358 |
+
)
|
| 1359 |
+
return self._permute_scratch
|
| 1360 |
+
|
| 1361 |
+
def workspace_shapes(
|
| 1362 |
+
self,
|
| 1363 |
+
M: int,
|
| 1364 |
+
N: int,
|
| 1365 |
+
K: int,
|
| 1366 |
+
topk: int,
|
| 1367 |
+
global_num_experts: int,
|
| 1368 |
+
local_num_experts: int,
|
| 1369 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 1370 |
+
activation: MoEActivation,
|
| 1371 |
+
) -> tuple[tuple[int, ...], tuple[int, ...], tuple[int, ...]]:
|
| 1372 |
+
activation_out_dim = self.adjust_N_for_activation(N, activation)
|
| 1373 |
+
workspace1 = (M * topk, max(N, K))
|
| 1374 |
+
workspace2 = (M * topk, max(activation_out_dim, K))
|
| 1375 |
+
output = (M, K)
|
| 1376 |
+
return (workspace1, workspace2, output)
|
| 1377 |
+
|
| 1378 |
+
def apply(
|
| 1379 |
+
self,
|
| 1380 |
+
output: torch.Tensor,
|
| 1381 |
+
hidden_states: torch.Tensor,
|
| 1382 |
+
w1: torch.Tensor,
|
| 1383 |
+
w2: torch.Tensor,
|
| 1384 |
+
topk_weights: torch.Tensor,
|
| 1385 |
+
topk_ids: torch.Tensor,
|
| 1386 |
+
activation: MoEActivation,
|
| 1387 |
+
global_num_experts: int,
|
| 1388 |
+
expert_map: torch.Tensor | None,
|
| 1389 |
+
a1q_scale: torch.Tensor | None,
|
| 1390 |
+
a2_scale: torch.Tensor | None,
|
| 1391 |
+
workspace13: torch.Tensor | None,
|
| 1392 |
+
workspace2: torch.Tensor | None,
|
| 1393 |
+
expert_tokens_meta: mk.ExpertTokensMetadata | None,
|
| 1394 |
+
apply_router_weight_on_input: bool,
|
| 1395 |
+
):
|
| 1396 |
+
assert self.w1_zp is None, "w1_zp is not supported in CUTLASS MoE"
|
| 1397 |
+
assert self.w2_zp is None, "w2_zp is not supported in CUTLASS MoE"
|
| 1398 |
+
|
| 1399 |
+
expert_num_tokens = None
|
| 1400 |
+
|
| 1401 |
+
use_batched_format = (
|
| 1402 |
+
self.activation_format() == mk.FusedMoEActivationFormat.BatchedExperts
|
| 1403 |
+
)
|
| 1404 |
+
assert not use_batched_format, "batched format not supported"
|
| 1405 |
+
|
| 1406 |
+
in_dtype = hidden_states.dtype
|
| 1407 |
+
|
| 1408 |
+
run_cutlass_moe_w4a8_fp8(
|
| 1409 |
+
output,
|
| 1410 |
+
hidden_states,
|
| 1411 |
+
w1,
|
| 1412 |
+
w2,
|
| 1413 |
+
topk_ids,
|
| 1414 |
+
activation,
|
| 1415 |
+
global_num_experts,
|
| 1416 |
+
expert_map,
|
| 1417 |
+
self.w1_scale,
|
| 1418 |
+
self.w2_scale,
|
| 1419 |
+
a1q_scale,
|
| 1420 |
+
a2_scale,
|
| 1421 |
+
self.g1_alphas, # per-channel scales
|
| 1422 |
+
self.g2_alphas, # per-channel scales
|
| 1423 |
+
self.a_strides1,
|
| 1424 |
+
self.a_strides2,
|
| 1425 |
+
self.b_strides1,
|
| 1426 |
+
self.b_strides2,
|
| 1427 |
+
self.c_strides1,
|
| 1428 |
+
self.c_strides2,
|
| 1429 |
+
self.s_strides1,
|
| 1430 |
+
self.s_strides2,
|
| 1431 |
+
workspace13,
|
| 1432 |
+
workspace2,
|
| 1433 |
+
expert_num_tokens,
|
| 1434 |
+
self.out_dtype if self.out_dtype is not None else in_dtype,
|
| 1435 |
+
self.per_act_token_quant,
|
| 1436 |
+
self.per_out_ch_quant,
|
| 1437 |
+
use_batched_format,
|
| 1438 |
+
topk_weights,
|
| 1439 |
+
self.group_size,
|
| 1440 |
+
self._get_permute_scratch(),
|
| 1441 |
+
)
|