Add tested native vLLM TP4 runtime, RTX PRO instructions and validation
Browse files- .gitattributes +2 -0
- LICENSE +21 -0
- README.md +202 -0
- SHA256SUMS +49 -0
- chat_template.jinja +160 -0
- compose.yml +53 -0
- config.json +342 -0
- configuration_naive_n05_flash.py +155 -0
- generation_config.json +9 -0
- hf_quant_config.json +110 -0
- model.safetensors.index.json +3 -0
- modeling_naive_n05_flash.py +243 -0
- quantization_provenance.json +61 -0
- runtime-lock.json +38 -0
- runtime/.dockerignore +2 -0
- runtime/Dockerfile +29 -0
- runtime/LICENSE +21 -0
- runtime/LICENSE-APACHE-2.0.txt +202 -0
- runtime/THIRD_PARTY_NOTICES.md +16 -0
- runtime/pyproject.toml +14 -0
- runtime/requirements.txt +6 -0
- runtime/scripts/benchmark_stream.py +84 -0
- runtime/scripts/decode_kernels.py +169 -0
- runtime/scripts/fused_experts.py +50 -0
- runtime/scripts/nvfp4_runtime.py +154 -0
- runtime/scripts/preflight.py +63 -0
- runtime/scripts/safe_device_transfer.py +30 -0
- runtime/scripts/validate_api.py +73 -0
- runtime/sitecustomize.py +7 -0
- runtime/vllm_naive/__init__.py +11 -0
- runtime/vllm_naive/attention.py +242 -0
- runtime/vllm_naive/model.py +189 -0
- tokenizer.json +3 -0
- tokenizer_config.json +32 -0
- validation/expert-sharding-tp4-validation.json +17 -0
- validation/export-validation.json +8 -0
- validation/native-tiny-graphs-validation.json +394 -0
- validation/native-vllm-api-validation.json +283 -0
- validation/native-vllm-benchmark-repeat.json +0 -0
- validation/native-vllm-benchmark.json +0 -0
- validation/native-vllm-concurrency-validation.json +184 -0
- validation/native-vllm-streaming-validation.json +1493 -0
- validation/portable-preflight.json +39 -0
- validation/preserved-weights-validation.json +10 -0
- validation/runtime-source-validation.json +17 -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 |
+
model.safetensors.index.json filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
tokenizer.json filter=lfs diff=lfs merge=lfs -text
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Naive AI
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
base_model: NaiveAI/Naive-N0.5-Flash
|
| 4 |
+
base_model_relation: quantized
|
| 5 |
+
library_name: vllm
|
| 6 |
+
pipeline_tag: text-generation
|
| 7 |
+
tags:
|
| 8 |
+
- nvfp4
|
| 9 |
+
- modelopt
|
| 10 |
+
- vllm
|
| 11 |
+
- mixture-of-experts
|
| 12 |
+
- custom-code
|
| 13 |
+
- blackwell
|
| 14 |
+
---
|
| 15 |
+
|
| 16 |
+
# Naive-N0.5-Flash NVFP4 — vLLM on four RTX PRO 6000 Blackwell GPUs
|
| 17 |
+
|
| 18 |
+
**Original model by [Naive AI](https://huggingface.co/NaiveAI). This release is built on their work.**
|
| 19 |
+
|
| 20 |
+
The Naive AI team created and openly released **Naive-N0.5-Flash**, including its sparse-attention adaptation, continued pretraining, model weights and reference implementation. Their research and engineering are the foundation of this repository. Many thanks to the team for sharing the model, code and technical details with the community and making derivatives like this possible.
|
| 21 |
+
|
| 22 |
+
**Please support and credit the original project:** [original model](https://huggingface.co/NaiveAI/Naive-N0.5-Flash) · [GitHub](https://github.com/NaiveAI-Labs/Naive-N0.5-Flash) · [technical report and research](https://naive.ai/en/research/) · [Naive AI](https://naive.ai/).
|
| 23 |
+
|
| 24 |
+
Naive's model in turn builds on **[Xiaomi MiMo-V2.5-Base](https://huggingface.co/XiaomiMiMo/MiMo-V2.5-Base)** and the **DeepSeek** team's sparse-attention research. Credit for that foundation belongs to those teams as well. This repository is an **unofficial community quantization and serving adaptation**: its contribution is the expert-only NVFP4 conversion, validation, and native vLLM integration for RTX PRO Blackwell hardware.
|
| 25 |
+
|
| 26 |
+
NVFP4 expert quantization of [NaiveAI/Naive-N0.5-Flash](https://huggingface.co/NaiveAI/Naive-N0.5-Flash), a sparse-attention derivative of Xiaomi MiMo-V2.5. The model has approximately 309B total parameters and 15.5B active parameters per token. The 49 weight shards occupy **182.57 GB** (170.03 GiB).
|
| 27 |
+
|
| 28 |
+
**Serve this checkpoint with the included native vLLM model plugin and Docker recipe below.** The tested engine is vLLM 0.28.0, with tensor parallelism across four 96 GB RTX PRO 6000 Blackwell GPUs. vLLM runs scheduling, paged KV-cache allocation, sampling, prefix caching, chunked prefill and the streaming OpenAI-compatible API. The plugin supplies Naive's model implementation and NVFP4 expert kernels.
|
| 29 |
+
|
| 30 |
+
Naive's architecture requires this plugin; the pinned stock vLLM image does not implement it. Installing the plugin is part of the Docker build. This repository does not provide a tested SGLang implementation. Keep the original `naive_n05_flash` architecture in `config.json`.
|
| 31 |
+
|
| 32 |
+
## Run with vLLM
|
| 33 |
+
|
| 34 |
+
The tested machine uses four **NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition 96 GB** GPUs (SM120), a Threadripper PRO 7955WX, 498 GiB host RAM, Linux and driver 595.91.07. Have Docker Compose and NVIDIA Container Toolkit working, with all four GPUs visible to containers. Allow roughly 250 GB of free disk for the checkpoint, container images and compilation caches. This recipe is validated on the four-GPU machine described here; smaller configurations have not been validated.
|
| 35 |
+
|
| 36 |
+
Download the release using the Hugging Face CLI:
|
| 37 |
+
|
| 38 |
+
```bash
|
| 39 |
+
hf download piotrkosecki/Naive-N0.5-Flash-NVFP4 \
|
| 40 |
+
--revision nvfp4-vllm-v1 \
|
| 41 |
+
--local-dir ./Naive-N0.5-Flash-NVFP4
|
| 42 |
+
cd Naive-N0.5-Flash-NVFP4
|
| 43 |
+
sha256sum --check SHA256SUMS
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
Build the pinned runtime, check the checkpoint and hardware, and start vLLM:
|
| 47 |
+
|
| 48 |
+
```bash
|
| 49 |
+
export LOCAL_UID="$(id -u)"
|
| 50 |
+
export LOCAL_GID="$(id -g)"
|
| 51 |
+
mkdir -p runtime-cache
|
| 52 |
+
docker compose build naive-vllm
|
| 53 |
+
docker compose run --rm --no-deps --entrypoint python3 naive-vllm \
|
| 54 |
+
/opt/naive/scripts/preflight.py
|
| 55 |
+
docker compose up -d naive-vllm
|
| 56 |
+
docker compose logs -f naive-vllm
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
Free the GPUs from other large models before starting. The recipe uses approximately 81–85 GiB per GPU, rising with workspaces and requests; desktop applications require additional memory. Keep `runtime-cache`: the first start and the first request of a new shape can compile kernels and take substantially longer. Cached starts still need model loading and graph capture. Wait for the API server to become ready:
|
| 60 |
+
|
| 61 |
+
```bash
|
| 62 |
+
curl --fail http://127.0.0.1:8000/health
|
| 63 |
+
curl --fail http://127.0.0.1:8000/version
|
| 64 |
+
curl --fail http://127.0.0.1:8000/v1/models
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
`/version` reports `0.28.0`; `/v1/models` lists `Naive-N0.5-Flash-NVFP4`. The API binds to localhost, and container restart is manual. Stop it with `docker compose stop naive-vllm`.
|
| 68 |
+
|
| 69 |
+
The image entrypoint is `python3 -m vllm.entrypoints.openai.api_server`. The full launch configuration is in [compose.yml](compose.yml); its vLLM arguments are:
|
| 70 |
+
|
| 71 |
+
```bash
|
| 72 |
+
--model /models/Naive-N0.5-Flash-NVFP4 \
|
| 73 |
+
--served-model-name Naive-N0.5-Flash-NVFP4 \
|
| 74 |
+
--trust-remote-code \
|
| 75 |
+
--tensor-parallel-size 4 --distributed-executor-backend mp \
|
| 76 |
+
--dtype bfloat16 --max-model-len 8192 \
|
| 77 |
+
--max-num-batched-tokens 256 --max-num-seqs 4 \
|
| 78 |
+
--kv-cache-memory-bytes 4294967296 \
|
| 79 |
+
--disable-custom-all-reduce \
|
| 80 |
+
--enable-prefix-caching --enable-chunked-prefill \
|
| 81 |
+
--compilation-config '{"mode":0,"cudagraph_mode":"FULL_DECODE_ONLY","cudagraph_capture_sizes":[1],"cudagraph_num_of_warmups":2}' \
|
| 82 |
+
--enable-auto-tool-choice --tool-call-parser mimo --reasoning-parser mimo \
|
| 83 |
+
--host 127.0.0.1 --port 8000
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
## Send requests
|
| 87 |
+
|
| 88 |
+
Streaming chat:
|
| 89 |
+
|
| 90 |
+
```bash
|
| 91 |
+
curl -N http://127.0.0.1:8000/v1/chat/completions \
|
| 92 |
+
-H 'Content-Type: application/json' \
|
| 93 |
+
-d '{
|
| 94 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 95 |
+
"messages": [{"role": "user", "content": "Explain how a hash table works."}],
|
| 96 |
+
"temperature": 0,
|
| 97 |
+
"max_tokens": 256,
|
| 98 |
+
"chat_template_kwargs": {"enable_thinking": false},
|
| 99 |
+
"stream": true,
|
| 100 |
+
"stream_options": {"include_usage": true}
|
| 101 |
+
}'
|
| 102 |
+
```
|
| 103 |
+
|
| 104 |
+
For an OpenAI-compatible client, use base URL `http://127.0.0.1:8000/v1` and model `Naive-N0.5-Flash-NVFP4`. No API key is configured; clients that require a value can use a placeholder.
|
| 105 |
+
|
| 106 |
+
For thinking, set `chat_template_kwargs` to `{"enable_thinking": true}` and allow enough output tokens. This vLLM version returns separate `message.reasoning` and `message.content` fields. Streaming responses use `delta.reasoning` and `delta.content`.
|
| 107 |
+
|
| 108 |
+
Tool calls use the normal OpenAI `tools` schema, for example:
|
| 109 |
+
|
| 110 |
+
```bash
|
| 111 |
+
curl http://127.0.0.1:8000/v1/chat/completions \
|
| 112 |
+
-H 'Content-Type: application/json' \
|
| 113 |
+
-d '{
|
| 114 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 115 |
+
"messages": [{"role": "user", "content": "Call get_weather for Warsaw."}],
|
| 116 |
+
"tools": [{"type": "function", "function": {
|
| 117 |
+
"name": "get_weather",
|
| 118 |
+
"description": "Get weather for a city",
|
| 119 |
+
"parameters": {"type": "object", "properties": {
|
| 120 |
+
"city": {"type": "string"}
|
| 121 |
+
}, "required": ["city"]}
|
| 122 |
+
}}],
|
| 123 |
+
"tool_choice": "auto",
|
| 124 |
+
"temperature": 0,
|
| 125 |
+
"max_tokens": 192,
|
| 126 |
+
"chat_template_kwargs": {"enable_thinking": false}
|
| 127 |
+
}'
|
| 128 |
+
```
|
| 129 |
+
|
| 130 |
+
## Measured performance and validation
|
| 131 |
+
|
| 132 |
+
Measured on September 28, 2026 with the final release build:
|
| 133 |
+
|
| 134 |
+
| Prompt tokens | Generated tokens | Decode tokens/sec | Time to first token (s) | End-to-end tokens/sec |
|
| 135 |
+
|---:|---:|---:|---:|---:|
|
| 136 |
+
| 76 | 256 | 56.56 | 0.074 | 55.87 |
|
| 137 |
+
| 79 | 256 | 56.56 | 0.076 | 55.85 |
|
| 138 |
+
| 1,685 | 256 | 56.44 | 0.484 | 51.18 |
|
| 139 |
+
| 3,845 | 256 | 56.57 | 0.611 | 50.01 |
|
| 140 |
+
| 7,445 | 256 | 56.44 | 1.113 | 45.46 |
|
| 141 |
+
|
| 142 |
+
A second run measured **55.00–55.11 tokens/sec** during decode. Both runs exceeded 50 tokens/sec in all five cases. Raw responses, token IDs, timestamps and usage counts are in [run 1](validation/native-vllm-benchmark.json) and [run 2](validation/native-vllm-benchmark-repeat.json).
|
| 143 |
+
|
| 144 |
+
These measurements use the full model in **native vLLM**, one active request, temperature 0 and 256 generated tokens per response. The client records token-bearing SSE events and checks the exact returned token IDs against vLLM's usage count. Decode rate is the number of tokens after the first event divided by the time from the first to the last token event. Prompt processing and time to first token are reported separately. Prefix caching is enabled; the long prompts share background text, and repeated prompts can reuse cached prefixes. The time-to-first-token column is not a cold-prefill benchmark. Compilation and prompt processing affect end-to-end speed.
|
| 145 |
+
|
| 146 |
+
CUDA graphs currently cover **one active decode request**. Multiple active requests run through the eager path and are slower per request. Four simultaneous requests passed a functional test; the single-request speeds above do not describe concurrency throughput.
|
| 147 |
+
|
| 148 |
+
Reproduce the checks while no other client is using the server:
|
| 149 |
+
|
| 150 |
+
```bash
|
| 151 |
+
python3 runtime/scripts/validate_api.py
|
| 152 |
+
python3 runtime/scripts/benchmark_stream.py \
|
| 153 |
+
--tokens 256 --cases 5 --output native-vllm-benchmark.json
|
| 154 |
+
```
|
| 155 |
+
|
| 156 |
+
Validation includes full-model arithmetic, geography, Python code, structured tool calls, reasoning, longer-context generation and four concurrent requests. Tiny-model tests compare 144 greedy tokens exactly with the quantized reference while exercising graph replay, batched scheduling, chunked prefill and prefix caching. A real expert layer was also checked with tensor-parallel slicing. Reports in [validation/](validation/) distinguish these checks from full-model measurements. These are smoke and implementation checks, not an evaluation of accuracy loss versus BF16 on a benchmark suite.
|
| 157 |
+
|
| 158 |
+
## Runtime limits and implementation
|
| 159 |
+
|
| 160 |
+
- Tested maximum context: **8,192 total input plus output tokens**, with prompts up to 7,445 tokens in the streamed benchmark. The source model's 1M context is not validated by this deployment.
|
| 161 |
+
- TP4, pipeline parallelism 1; 256-token prefill chunks; up to four scheduled sequences; 4 GiB cache budget per GPU, with 17,472 cache tokens shared across requests (about two full 8K requests). Longer concurrent workloads can require vLLM to preempt and recompute requests. Attention K/V are BF16 values stored losslessly in FP32 cache slots alongside FP8-rounded indexer values with FP32 scales. KV cache is not NVFP4.
|
| 162 |
+
- Single-token execution fuses RMS normalization, Q/K/V projection and rotary embedding operations, while retaining source BF16 rounding points.
|
| 163 |
+
- The plugin preserves the source sliding window of 128, sparse selection of up to 2,048 tokens, stable indexer tie ordering and original attention value scaling.
|
| 164 |
+
- `NCCL_P2P_DISABLE=1` and `--disable-custom-all-reduce` are required by the tested workstation's failed direct peer-copy integrity checks. The recipe keeps those settings and uses NCCL's host transport.
|
| 165 |
+
- FlashInfer 0.7.0's direct-micro expert path returned zeros for this checkpoint's TP4 shape. The plugin disables that path and uses its validated regular MMA micro/static/dynamic kernels. This workaround depends on the pinned FlashInfer version.
|
| 166 |
+
- `sitecustomize.py` isolates FlashInfer 0.7 source-built kernels from the base image's older prebuilt cubins. Keep the supplied dependency pins and persistent cache directories.
|
| 167 |
+
|
| 168 |
+
The [Dockerfile](runtime/Dockerfile) pins the public vLLM base image by digest. Tested versions: vLLM 0.28.0, PyTorch 2.13.0+cu130, Transformers 5.17.0, FlashInfer 0.7.0, CUTLASS DSL 4.6.2 and Triton 3.7.1. The plugin uses vLLM's [model registration mechanism](https://docs.vllm.ai/en/latest/design/plugin_system/) and is included as source in [runtime/vllm_naive/](runtime/vllm_naive/).
|
| 169 |
+
|
| 170 |
+
## Quantization and provenance
|
| 171 |
+
|
| 172 |
+
Source revision: [`0235b3b5ff27422b1f57cdc2acddfaf643e08356`](https://huggingface.co/NaiveAI/Naive-N0.5-Flash/tree/0235b3b5ff27422b1f57cdc2acddfaf643e08356). NVIDIA Model Optimizer revision: [`23355eda90a25c290f9b1fdfb928ad54caae7d10`](https://github.com/NVIDIA/Model-Optimizer/tree/23355eda90a25c290f9b1fdfb928ad54caae7d10).
|
| 173 |
+
|
| 174 |
+
Only routed experts are quantized: NVFP4 E2M1 weights and activations, block size 16, FP8 block scales and FP32 global scales. Attention, indexer, router, embeddings and output head retain source precision. All 472 non-expert tensors match source shapes, dtypes and payload hashes. There are 36,096 packed expert matrices and 144,856 exported tensors; total tensor payload is 182,549,965,184 bytes.
|
| 175 |
+
|
| 176 |
+
Layerwise max calibration used 128 sequences of 4,096 tokens (524,288 total), equally divided between Magicoder OSS Instruct and UltraChat, with seed 20260928. Exact dataset revisions and calibration hash are in [quantization_provenance.json](quantization_provenance.json). Layer 47's router was materialized in BF16 during calibration; the final router was restored byte-for-byte from the FP32 source. An exporter naming issue required reconstructing the unchanged embedding, final norm and output-head tail; all 48 calibrated layer shards were retained and the complete export was subsequently audited.
|
| 177 |
+
|
| 178 |
+
The source model's MIT license is preserved in [LICENSE](LICENSE). Upstream configuration/modeling files retain their Apache-2.0 headers. Additional runtime code is MIT licensed; see [runtime/THIRD_PARTY_NOTICES.md](runtime/THIRD_PARTY_NOTICES.md).
|
| 179 |
+
|
| 180 |
+
## Acknowledgments and citation
|
| 181 |
+
|
| 182 |
+
This release depends on substantial work by the original model authors and the open-source inference community:
|
| 183 |
+
|
| 184 |
+
- **[Naive AI / NaiveAI Team](https://github.com/NaiveAI-Labs/Naive-N0.5-Flash)** — creation and release of Naive-N0.5-Flash, the hybrid SWA/DSA adaptation, continued pretraining, checkpoint, chat template, model implementation and research documentation. Please cite their work when using this derivative.
|
| 185 |
+
- **[Xiaomi MiMo](https://huggingface.co/XiaomiMiMo/MiMo-V2.5-Base)** — the MiMo-V2.5 base model on which Naive-N0.5-Flash builds.
|
| 186 |
+
- **[DeepSeek](https://github.com/deepseek-ai)** — the DeepSeek Sparse Attention research underpinning Naive's sparse-attention design.
|
| 187 |
+
- **[vLLM](https://github.com/vllm-project/vllm)** and **[FlashInfer](https://github.com/flashinfer-ai/flashinfer)** — the serving engine and Blackwell NVFP4 expert kernels used in this deployment.
|
| 188 |
+
- **[NVIDIA Model Optimizer](https://github.com/NVIDIA/Model-Optimizer)** and **[CUTLASS](https://github.com/NVIDIA/cutlass)** — quantization tooling and GPU kernel infrastructure.
|
| 189 |
+
- **[Hugging Face Transformers](https://github.com/huggingface/transformers)**, **[PyTorch](https://github.com/pytorch/pytorch)** and **[Triton](https://github.com/triton-lang/triton)** — model-loading, tensor-computation and kernel-building infrastructure.
|
| 190 |
+
|
| 191 |
+
The original weights and their capabilities come from the upstream model teams. This quantized release retains Naive AI's model identity, copyright notices and license. Please direct recognition for the model and its research to the original authors.
|
| 192 |
+
|
| 193 |
+
The following is the citation supplied by Naive AI in the original model card:
|
| 194 |
+
|
| 195 |
+
```bibtex
|
| 196 |
+
@misc{naiveai2026naiven05flash,
|
| 197 |
+
title = {Naive-N0.5-Flash: Building Frontier AI with AI},
|
| 198 |
+
author = {{NaiveAI Team}},
|
| 199 |
+
year = {2026},
|
| 200 |
+
url = {https://naive.ai/en/research/}
|
| 201 |
+
}
|
| 202 |
+
```
|
SHA256SUMS
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
5a5221799458f4f22a969ff5bb06556e74dc214f2168da14dac077e13661c4a5 model-layer-00000.safetensors
|
| 2 |
+
ea02f0c21f403c1b080582f57875e8851a4a77056a2bbb50c1041fd8f2b342e2 model-layer-00001.safetensors
|
| 3 |
+
04c06288df5a794cff43965020272a2e611e52dccc82f85ae4b3a2412b717ff0 model-layer-00002.safetensors
|
| 4 |
+
afde47709532dedae9fc9b3e3b140e31ed2d0027db4461355bc8c00660d95af3 model-layer-00003.safetensors
|
| 5 |
+
13f9ac46ef988032fab0a064a99101a98b0d466da3d743616213aae4d693d607 model-layer-00004.safetensors
|
| 6 |
+
f44cd75dd4060562fcc108614d3104c7c4cda48ef239ee785c50336ecaecb176 model-layer-00005.safetensors
|
| 7 |
+
01910d46a12010345a37136155477ef8eff738af39adf6125254b18f1e7405a8 model-layer-00006.safetensors
|
| 8 |
+
017f899ba6c6890182c334299fb09daa17068e07761c741e1235c7a2ef15075e model-layer-00007.safetensors
|
| 9 |
+
fa9b19c4633a4bc4e0d83768f5a721c35e7abb049cc0e7a9be0d50d2749038a0 model-layer-00008.safetensors
|
| 10 |
+
1359abf1ed7f385a2cf5d16b3863eb0db5ed34a182d1e99fadbecfd0a0b6370f model-layer-00009.safetensors
|
| 11 |
+
9f09fd2abf17a4ef2da924785444801edec40a7c52ed84c4c4057f48153d0bf0 model-layer-00010.safetensors
|
| 12 |
+
1dc08baf20ef80bec9c1219f60ba3267b5dc4eaf7dc8cdf4a0c933c05851cd6b model-layer-00011.safetensors
|
| 13 |
+
654df6d13f2d250fd87a058219350147435207d5e235a74cf5dddefcbffa6afc model-layer-00012.safetensors
|
| 14 |
+
803c042c1014924977feead399e9d16198dbb63cad43ed2c2340cdcfcb3487ef model-layer-00013.safetensors
|
| 15 |
+
67ef2e7acc1bf743a8dc43145ad51ac129913fe76060aa3ab19c220b68ad7919 model-layer-00014.safetensors
|
| 16 |
+
053f9b45fa2c66a1e19662327532812ac242a8649dec9c457b1c95030d6e7bdb model-layer-00015.safetensors
|
| 17 |
+
ee2d0ea2c37f897482e5ebd158a1f7069785962cd48966ebee9d6f1c5e925cb5 model-layer-00016.safetensors
|
| 18 |
+
7964ccac2a882f7ed6c391717837a82a1a94d4b3063348d27abeae121c847105 model-layer-00017.safetensors
|
| 19 |
+
30b2b7bf5cc74bc4564dc820c0e486ebf72815e70b57f01cc5fa1fed512412c1 model-layer-00018.safetensors
|
| 20 |
+
ee74c25f2b33a5a3909083a95bbc25572bfbcc27644600a30cc07a0810c7729a model-layer-00019.safetensors
|
| 21 |
+
a60ad1d87b423286e9e0c19734021e6da48af9f96bbb101ddde8dbffc5f490bb model-layer-00020.safetensors
|
| 22 |
+
a36d517f3a1c629afc88d9ed1da8e41ebae34da3bfc28bd4cd5421161203919c model-layer-00021.safetensors
|
| 23 |
+
c17ef7ede6621cbef4af19e1c1cb90262c5c1a8569e96305314399d9e4743117 model-layer-00022.safetensors
|
| 24 |
+
a3945a6ccd6f8eb49f2fd031c7157c67fdf8be240a5aaf3d264e9d8cef9363ff model-layer-00023.safetensors
|
| 25 |
+
96de6d3bb2d725f181c8c573ed367db5b3c6bdcffe4664b2ac4b79732fe46928 model-layer-00024.safetensors
|
| 26 |
+
38b03b993fc0d1faa1561d68dadd92d16016d6c8f1ff45bb878f50eac5187d97 model-layer-00025.safetensors
|
| 27 |
+
18a984e0005858c6966cd3583d102cf1449cfb33b4eb956da39fbb7f0201f7b0 model-layer-00026.safetensors
|
| 28 |
+
71b43db7c49d79c9f4e781607368fa427689bc83f04170e07d8f492b004c715b model-layer-00027.safetensors
|
| 29 |
+
9721a3937de1e68c04b7f27e473c66f027a99db08c183a62f5066a618d204c2f model-layer-00028.safetensors
|
| 30 |
+
6379291e260ff9c7e6464fb8575bcda918cd2cced4a8aa4c4df25b753fd3c6a8 model-layer-00029.safetensors
|
| 31 |
+
5a8d77fa6ad0d1ade6fc09412bbc024234cf29500e72f275eb7d0f29635396d3 model-layer-00030.safetensors
|
| 32 |
+
266f83df2664128a809e73c5a4a66d52f561e12e490d097e767210076d8ac3c7 model-layer-00031.safetensors
|
| 33 |
+
7fbbe022dee5c5a1abc2f34e4e8233f0889c3a6c136f4a8ade2a30fceb47198f model-layer-00032.safetensors
|
| 34 |
+
2c9ee12a7ffab178f83ae09b4b32f7d47d0d3f1d66f015b37219684b4fb2fbe5 model-layer-00033.safetensors
|
| 35 |
+
27741fe3a2ce23fd6aec824eed1c6368027d5b4c7ea7aa2f789ad86058cad2a7 model-layer-00034.safetensors
|
| 36 |
+
73de4529e86bad56ea9214e72173f1395e118aa560267eff3089b05d1d895b55 model-layer-00035.safetensors
|
| 37 |
+
e342456af59dd2f1cd9af768495671a55247ebf44005c91d951d8b1fa203022b model-layer-00036.safetensors
|
| 38 |
+
b1b31e1a4c70987d53af10c6b69da05b4a6089eaac1beec0fdcbcafc639e17eb model-layer-00037.safetensors
|
| 39 |
+
2f96937c417f671c23184c6b5c0ae7557c3d9647d59b689a10a3ce47eb40fe7c model-layer-00038.safetensors
|
| 40 |
+
bd1cd8474660df1ae8211ca1ca94b3340727f8f8e35ebe00022837d837952c95 model-layer-00039.safetensors
|
| 41 |
+
5cdcdb39f00310dcce5f0e744a063b83d3fbed1ea30d888827a807302775f2b5 model-layer-00040.safetensors
|
| 42 |
+
b08cdd0830ba4d69de116de6bc84faa92882c8ce44e42c56fa93639067b94225 model-layer-00041.safetensors
|
| 43 |
+
142512bab040f4024047142e4f4da369d0d088b87773c16863716c2b9e56379b model-layer-00042.safetensors
|
| 44 |
+
ee5c93564e067b630d5f7638711b9d1c01ec6a78beff5714ce749c2c97279b1f model-layer-00043.safetensors
|
| 45 |
+
59b9a9e0120ba64dd6661c57b2c30522a03a8eee6cf3d7d93e1ea267af72a148 model-layer-00044.safetensors
|
| 46 |
+
c63b3fe88aef75eb0066d7dd5abe30b80d174b9e82be843cd43f0f7e5977b56e model-layer-00045.safetensors
|
| 47 |
+
8f53dd271c1f77f684d70673817f0f74142c7ca78e1f2fde6af422e201f2ad38 model-layer-00046.safetensors
|
| 48 |
+
5a2dc73e627443f2f95dee391123ef4e069d2ad03bffaf13026b6e012ea22803 model-layer-00047.safetensors
|
| 49 |
+
6394124320964e6dbed2069d11d045c1ee2e8ec4a580c293e2987f1ea1ab6d9c model-tail.safetensors
|
chat_template.jinja
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{%- set effective_reasoning_effort = reasoning_effort if reasoning_effort is defined and reasoning_effort in ['low', 'high'] else 'max' -%}
|
| 2 |
+
{%- if effective_reasoning_effort is not none -%}
|
| 3 |
+
{{- "<|im_start|>system\nReasoning Effort: " ~ (effective_reasoning_effort | capitalize) ~ "<|im_end|>" }}
|
| 4 |
+
{%- endif -%}
|
| 5 |
+
{%- if not add_generation_prompt is defined -%}
|
| 6 |
+
{%- set add_generation_prompt = false -%}
|
| 7 |
+
{%- endif -%}
|
| 8 |
+
{%- if not enable_thinking is defined -%}
|
| 9 |
+
{%- set enable_thinking = true -%}
|
| 10 |
+
{%- endif -%}
|
| 11 |
+
{%- if not keep_all_reasoning is defined -%}
|
| 12 |
+
{%- set keep_all_reasoning = true -%}
|
| 13 |
+
{%- endif -%}
|
| 14 |
+
{%- macro render_extra_keys(json_dict, handled_keys) -%}
|
| 15 |
+
{%- if json_dict is mapping %}
|
| 16 |
+
{%- for json_key in json_dict if json_key not in handled_keys %}
|
| 17 |
+
{%- if json_dict[json_key] is mapping or (json_dict[json_key] is sequence and json_dict[json_key] is not string) %}
|
| 18 |
+
{{- '\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | tojson | safe) ~ '</' ~ json_key ~ '>' }}
|
| 19 |
+
{%- else %}
|
| 20 |
+
{{-'\n<' ~ json_key ~ '>' ~ (json_dict[json_key] | string) ~ '</' ~ json_key ~ '>' }}
|
| 21 |
+
{%- endif %}
|
| 22 |
+
{%- endfor %}
|
| 23 |
+
{%- endif %}
|
| 24 |
+
{%- endmacro -%}
|
| 25 |
+
{%- macro render_content(message_content) -%}
|
| 26 |
+
{%- if message_content is string -%}
|
| 27 |
+
{{- message_content -}}
|
| 28 |
+
{%- else -%}
|
| 29 |
+
{%- for content in message_content -%}
|
| 30 |
+
{%- if 'text' in content -%}
|
| 31 |
+
{{- content['text'] -}}
|
| 32 |
+
{%- endif -%}
|
| 33 |
+
{%- endfor -%}
|
| 34 |
+
{%- endif -%}
|
| 35 |
+
{%- endmacro -%}
|
| 36 |
+
{%- if messages[0]["role"] == "system" %}
|
| 37 |
+
{%- set system_message = messages[0]["content"] %}
|
| 38 |
+
{%- set loop_messages = messages[1:] %}
|
| 39 |
+
{%- else %}
|
| 40 |
+
{%- set loop_messages = messages %}
|
| 41 |
+
{%- endif %}
|
| 42 |
+
{%- set ns = namespace(last_user_index=-1) %}
|
| 43 |
+
{%- for m in loop_messages %}
|
| 44 |
+
{%- if m.role == 'user' %}
|
| 45 |
+
{%- set ns.last_user_index = loop.index0 -%}
|
| 46 |
+
{%- endif %}
|
| 47 |
+
{%- endfor %}
|
| 48 |
+
{%- if not tools is defined %}
|
| 49 |
+
{%- set tools = [] %}
|
| 50 |
+
{%- endif %}
|
| 51 |
+
{%- if system_message is defined %}
|
| 52 |
+
{{- "<|im_start|>system\n" + render_content(system_message) }}
|
| 53 |
+
{%- else %}
|
| 54 |
+
{{- "<|im_start|>system\nYou are Naive-N0.5-Flash, a helpful AI assistant engineered by Naive AI." }}
|
| 55 |
+
{%- endif %}
|
| 56 |
+
{%- if tools is iterable and tools | length > 0 %}
|
| 57 |
+
{{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou have access to the following functions:\n\n" }}
|
| 58 |
+
{{- "<tools>" }}
|
| 59 |
+
{%- for tool in tools %}
|
| 60 |
+
{%- if tool.function is defined %}
|
| 61 |
+
{%- set tool = tool.function %}
|
| 62 |
+
{%- endif %}
|
| 63 |
+
{{- "\n<function>\n<name>" ~ tool.name ~ "</name>" }}
|
| 64 |
+
{%- if tool.description is defined %}
|
| 65 |
+
{{- '\n<description>' ~ (tool.description | trim) ~ '</description>' }}
|
| 66 |
+
{%- endif %}
|
| 67 |
+
{{- '\n<parameters>' }}
|
| 68 |
+
{%- if tool.parameters is defined and tool.parameters is mapping and tool.parameters.properties is defined and tool.parameters.properties is mapping %}
|
| 69 |
+
{%- for param_name, param_fields in tool.parameters.properties|items %}
|
| 70 |
+
{{- '\n<parameter>' }}
|
| 71 |
+
{{- '\n<name>' ~ param_name ~ '</name>' }}
|
| 72 |
+
{%- if param_fields.type is defined %}
|
| 73 |
+
{{- '\n<type>' ~ (param_fields.type | string) ~ '</type>' }}
|
| 74 |
+
{%- endif %}
|
| 75 |
+
{%- if param_fields.description is defined %}
|
| 76 |
+
{{- '\n<description>' ~ (param_fields.description | trim) ~ '</description>' }}
|
| 77 |
+
{%- endif %}
|
| 78 |
+
{%- set handled_keys = ['name', 'type', 'description'] %}
|
| 79 |
+
{{- render_extra_keys(param_fields, handled_keys) }}
|
| 80 |
+
{{- '\n</parameter>' }}
|
| 81 |
+
{%- endfor %}
|
| 82 |
+
{%- endif %}
|
| 83 |
+
{%- set handled_keys = ['type', 'properties'] %}
|
| 84 |
+
{{- render_extra_keys(tool.parameters, handled_keys) }}
|
| 85 |
+
{{- '\n</parameters>' }}
|
| 86 |
+
{%- set handled_keys = ['type', 'name', 'description', 'parameters'] %}
|
| 87 |
+
{{- render_extra_keys(tool, handled_keys) }}
|
| 88 |
+
{{- '\n</function>' }}
|
| 89 |
+
{%- endfor %}
|
| 90 |
+
{{- "\n</tools>" }}
|
| 91 |
+
{{- '\n\nFor each function call, output the function name and arguments in the following format:\n<tool_call>\n<function=example_function_name>\n<parameter=example_parameter_1>value_1</parameter>\n<parameter=example_parameter_2>This is the value for the second parameter\nthat can span\nmultiple lines</parameter>\n</function>\n</tool_call>\n\n<IMPORTANT>\n- Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags\n- DO NOT use function calls inside <think></think> tags.\n- The value enclosed between parameter tags is preserved exactly as-is, including newlines and spaces.\n</IMPORTANT>' }}
|
| 92 |
+
{%- endif %}
|
| 93 |
+
{{- '<|im_end|>' }}
|
| 94 |
+
{%- for message in loop_messages %}
|
| 95 |
+
{%- if message.content is string %}
|
| 96 |
+
{%- set content = message.content %}
|
| 97 |
+
{%- else %}
|
| 98 |
+
{%- set content = render_content(message.content) %}
|
| 99 |
+
{%- endif %}
|
| 100 |
+
{%- if message.role == "assistant" %}
|
| 101 |
+
{%- if message.reasoning_content is string %}
|
| 102 |
+
{%- set reasoning_content = message.reasoning_content %}
|
| 103 |
+
{%- else %}
|
| 104 |
+
{%- set reasoning_content = '' %}
|
| 105 |
+
{%- if '</think>' in content %}
|
| 106 |
+
{%- set reasoning_content = content.split('</think>')[0].split('<think>')[-1] %}
|
| 107 |
+
{%- set content = content.split('</think>')[-1] %}
|
| 108 |
+
{%- endif %}
|
| 109 |
+
{%- endif %}
|
| 110 |
+
{%- if (keep_all_reasoning or loop.index0 > ns.last_user_index) and reasoning_content -%}
|
| 111 |
+
{{- '<|im_start|>' + message.role + '\n<think>' + reasoning_content + '</think>' + content }}
|
| 112 |
+
{%- else %}
|
| 113 |
+
{{- '<|im_start|>' + message.role + '\n<think></think>' + content }}
|
| 114 |
+
{%- endif %}
|
| 115 |
+
{%- if message.tool_calls is defined and message.tool_calls is iterable and message.tool_calls | length > 0 %}
|
| 116 |
+
{%- for tool_call in message.tool_calls %}
|
| 117 |
+
{%- if tool_call.function is defined %}
|
| 118 |
+
{%- set tool_call = tool_call.function %}
|
| 119 |
+
{%- endif %}
|
| 120 |
+
{{- '<tool_call>\n<function=' + tool_call.name + '>\n' }}
|
| 121 |
+
{%- if tool_call.arguments is defined %}
|
| 122 |
+
{%- for args_name, args_value in tool_call.arguments|items %}
|
| 123 |
+
{{- '<parameter=' + args_name + '>' }}
|
| 124 |
+
{%- set args_value = args_value | tojson | safe if args_value is mapping or (args_value is sequence and args_value is not string) else args_value | string %}
|
| 125 |
+
{{- args_value }}
|
| 126 |
+
{{- '</parameter>\n' }}
|
| 127 |
+
{%- endfor %}
|
| 128 |
+
{%- endif %}
|
| 129 |
+
{{- '</function>\n</tool_call>' }}
|
| 130 |
+
{%- endfor %}
|
| 131 |
+
{%- endif %}
|
| 132 |
+
{{- '<|im_end|>' }}
|
| 133 |
+
{%- elif message.role == "user" %}
|
| 134 |
+
{{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
|
| 135 |
+
{%- elif message.role == "system" %}
|
| 136 |
+
{{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
|
| 137 |
+
{%- elif message.role == "tool" %}
|
| 138 |
+
{%- if loop.previtem and loop.previtem.role != "tool" %}
|
| 139 |
+
{{- '<|im_start|>tool\n' }}
|
| 140 |
+
{%- endif %}
|
| 141 |
+
{{- '<tool_response>\n' }}
|
| 142 |
+
{{- render_content(message.content) }}
|
| 143 |
+
{{- '\n</tool_response>\n' }}
|
| 144 |
+
{%- if not loop.last and loop.nextitem.role != "tool" %}
|
| 145 |
+
{{- '<|im_end|>' }}
|
| 146 |
+
{%- elif loop.last %}
|
| 147 |
+
{{- '<|im_end|>' }}
|
| 148 |
+
{%- endif %}
|
| 149 |
+
{%- else %}
|
| 150 |
+
{{- '<|im_start|>' + message.role + '\n' + render_content(message.content) + '<|im_end|>' }}
|
| 151 |
+
{%- endif %}
|
| 152 |
+
{%- endfor %}
|
| 153 |
+
{%- if add_generation_prompt %}
|
| 154 |
+
{{- '<|im_start|>assistant\n' }}
|
| 155 |
+
{%- if not enable_thinking -%}
|
| 156 |
+
{{- '<think></think>' -}}
|
| 157 |
+
{%- else -%}
|
| 158 |
+
{{- '' -}}
|
| 159 |
+
{%- endif -%}
|
| 160 |
+
{%- endif %}
|
compose.yml
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
services:
|
| 2 |
+
naive-vllm:
|
| 3 |
+
build: ./runtime
|
| 4 |
+
image: naive-n05-vllm:local
|
| 5 |
+
container_name: naive-n05-vllm
|
| 6 |
+
user: "${LOCAL_UID:-1000}:${LOCAL_GID:-1000}"
|
| 7 |
+
network_mode: host
|
| 8 |
+
ipc: host
|
| 9 |
+
restart: "no"
|
| 10 |
+
gpus: all
|
| 11 |
+
environment:
|
| 12 |
+
CUDA_VISIBLE_DEVICES: "0,1,2,3"
|
| 13 |
+
MODEL_PATH: /models/Naive-N0.5-Flash-NVFP4
|
| 14 |
+
NCCL_P2P_DISABLE: "1"
|
| 15 |
+
OMP_NUM_THREADS: "1"
|
| 16 |
+
VLLM_FLOAT32_MATMUL_PRECISION: highest
|
| 17 |
+
volumes:
|
| 18 |
+
- ./:/models/Naive-N0.5-Flash-NVFP4:ro
|
| 19 |
+
- ./runtime-cache:/cache
|
| 20 |
+
command:
|
| 21 |
+
- --model
|
| 22 |
+
- /models/Naive-N0.5-Flash-NVFP4
|
| 23 |
+
- --served-model-name
|
| 24 |
+
- Naive-N0.5-Flash-NVFP4
|
| 25 |
+
- --trust-remote-code
|
| 26 |
+
- --tensor-parallel-size
|
| 27 |
+
- "4"
|
| 28 |
+
- --distributed-executor-backend
|
| 29 |
+
- mp
|
| 30 |
+
- --dtype
|
| 31 |
+
- bfloat16
|
| 32 |
+
- --max-model-len
|
| 33 |
+
- "8192"
|
| 34 |
+
- --max-num-batched-tokens
|
| 35 |
+
- "256"
|
| 36 |
+
- --max-num-seqs
|
| 37 |
+
- "4"
|
| 38 |
+
- --kv-cache-memory-bytes
|
| 39 |
+
- "4294967296"
|
| 40 |
+
- --disable-custom-all-reduce
|
| 41 |
+
- --enable-prefix-caching
|
| 42 |
+
- --enable-chunked-prefill
|
| 43 |
+
- --compilation-config
|
| 44 |
+
- '{"mode":0,"cudagraph_mode":"FULL_DECODE_ONLY","cudagraph_capture_sizes":[1],"cudagraph_num_of_warmups":2}'
|
| 45 |
+
- --enable-auto-tool-choice
|
| 46 |
+
- --tool-call-parser
|
| 47 |
+
- mimo
|
| 48 |
+
- --reasoning-parser
|
| 49 |
+
- mimo
|
| 50 |
+
- --host
|
| 51 |
+
- "127.0.0.1"
|
| 52 |
+
- --port
|
| 53 |
+
- "8000"
|
config.json
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"add_full_attention_sink_bias": false,
|
| 3 |
+
"add_swa_attention_sink_bias": true,
|
| 4 |
+
"architectures": [
|
| 5 |
+
"NaiveN05FlashForCausalLM"
|
| 6 |
+
],
|
| 7 |
+
"attention_bias": false,
|
| 8 |
+
"attention_chunk_size": 128,
|
| 9 |
+
"attention_dropout": 0.0,
|
| 10 |
+
"attention_projection_layout": "split",
|
| 11 |
+
"attention_value_scale": 0.707,
|
| 12 |
+
"auto_map": {
|
| 13 |
+
"AutoConfig": "configuration_naive_n05_flash.NaiveN05FlashConfig",
|
| 14 |
+
"AutoModel": "modeling_naive_n05_flash.NaiveN05FlashModel",
|
| 15 |
+
"AutoModelForCausalLM": "modeling_naive_n05_flash.NaiveN05FlashForCausalLM"
|
| 16 |
+
},
|
| 17 |
+
"dtype": "bfloat16",
|
| 18 |
+
"enable_dsa": true,
|
| 19 |
+
"eos_token_id": 151645,
|
| 20 |
+
"head_dim": 192,
|
| 21 |
+
"hidden_act": "silu",
|
| 22 |
+
"hidden_size": 4096,
|
| 23 |
+
"hybrid_block_size": null,
|
| 24 |
+
"hybrid_layer_pattern": [
|
| 25 |
+
0,
|
| 26 |
+
1,
|
| 27 |
+
1,
|
| 28 |
+
1,
|
| 29 |
+
1,
|
| 30 |
+
0,
|
| 31 |
+
1,
|
| 32 |
+
1,
|
| 33 |
+
1,
|
| 34 |
+
1,
|
| 35 |
+
1,
|
| 36 |
+
0,
|
| 37 |
+
1,
|
| 38 |
+
1,
|
| 39 |
+
1,
|
| 40 |
+
1,
|
| 41 |
+
1,
|
| 42 |
+
0,
|
| 43 |
+
1,
|
| 44 |
+
1,
|
| 45 |
+
1,
|
| 46 |
+
1,
|
| 47 |
+
1,
|
| 48 |
+
0,
|
| 49 |
+
1,
|
| 50 |
+
1,
|
| 51 |
+
1,
|
| 52 |
+
1,
|
| 53 |
+
1,
|
| 54 |
+
0,
|
| 55 |
+
1,
|
| 56 |
+
1,
|
| 57 |
+
1,
|
| 58 |
+
1,
|
| 59 |
+
1,
|
| 60 |
+
0,
|
| 61 |
+
1,
|
| 62 |
+
1,
|
| 63 |
+
1,
|
| 64 |
+
1,
|
| 65 |
+
1,
|
| 66 |
+
0,
|
| 67 |
+
1,
|
| 68 |
+
1,
|
| 69 |
+
1,
|
| 70 |
+
1,
|
| 71 |
+
1,
|
| 72 |
+
0
|
| 73 |
+
],
|
| 74 |
+
"index_head_dim": 128,
|
| 75 |
+
"index_n_heads": 16,
|
| 76 |
+
"index_n_kv_heads": 1,
|
| 77 |
+
"index_top_k": 2048,
|
| 78 |
+
"indexer_activation_dtype": "fp8_e4m3",
|
| 79 |
+
"initializer_range": 0.02,
|
| 80 |
+
"intermediate_size": 16384,
|
| 81 |
+
"layer_types": [
|
| 82 |
+
"deepseek_sparse_attention",
|
| 83 |
+
"sliding_attention",
|
| 84 |
+
"sliding_attention",
|
| 85 |
+
"sliding_attention",
|
| 86 |
+
"sliding_attention",
|
| 87 |
+
"deepseek_sparse_attention",
|
| 88 |
+
"sliding_attention",
|
| 89 |
+
"sliding_attention",
|
| 90 |
+
"sliding_attention",
|
| 91 |
+
"sliding_attention",
|
| 92 |
+
"sliding_attention",
|
| 93 |
+
"deepseek_sparse_attention",
|
| 94 |
+
"sliding_attention",
|
| 95 |
+
"sliding_attention",
|
| 96 |
+
"sliding_attention",
|
| 97 |
+
"sliding_attention",
|
| 98 |
+
"sliding_attention",
|
| 99 |
+
"deepseek_sparse_attention",
|
| 100 |
+
"sliding_attention",
|
| 101 |
+
"sliding_attention",
|
| 102 |
+
"sliding_attention",
|
| 103 |
+
"sliding_attention",
|
| 104 |
+
"sliding_attention",
|
| 105 |
+
"deepseek_sparse_attention",
|
| 106 |
+
"sliding_attention",
|
| 107 |
+
"sliding_attention",
|
| 108 |
+
"sliding_attention",
|
| 109 |
+
"sliding_attention",
|
| 110 |
+
"sliding_attention",
|
| 111 |
+
"deepseek_sparse_attention",
|
| 112 |
+
"sliding_attention",
|
| 113 |
+
"sliding_attention",
|
| 114 |
+
"sliding_attention",
|
| 115 |
+
"sliding_attention",
|
| 116 |
+
"sliding_attention",
|
| 117 |
+
"deepseek_sparse_attention",
|
| 118 |
+
"sliding_attention",
|
| 119 |
+
"sliding_attention",
|
| 120 |
+
"sliding_attention",
|
| 121 |
+
"sliding_attention",
|
| 122 |
+
"sliding_attention",
|
| 123 |
+
"deepseek_sparse_attention",
|
| 124 |
+
"sliding_attention",
|
| 125 |
+
"sliding_attention",
|
| 126 |
+
"sliding_attention",
|
| 127 |
+
"sliding_attention",
|
| 128 |
+
"sliding_attention",
|
| 129 |
+
"deepseek_sparse_attention"
|
| 130 |
+
],
|
| 131 |
+
"layernorm_epsilon": 1e-05,
|
| 132 |
+
"max_position_embeddings": 1048576,
|
| 133 |
+
"model_type": "naive_n05_flash",
|
| 134 |
+
"moe_intermediate_size": 2048,
|
| 135 |
+
"moe_layer_freq": [
|
| 136 |
+
0,
|
| 137 |
+
1,
|
| 138 |
+
1,
|
| 139 |
+
1,
|
| 140 |
+
1,
|
| 141 |
+
1,
|
| 142 |
+
1,
|
| 143 |
+
1,
|
| 144 |
+
1,
|
| 145 |
+
1,
|
| 146 |
+
1,
|
| 147 |
+
1,
|
| 148 |
+
1,
|
| 149 |
+
1,
|
| 150 |
+
1,
|
| 151 |
+
1,
|
| 152 |
+
1,
|
| 153 |
+
1,
|
| 154 |
+
1,
|
| 155 |
+
1,
|
| 156 |
+
1,
|
| 157 |
+
1,
|
| 158 |
+
1,
|
| 159 |
+
1,
|
| 160 |
+
1,
|
| 161 |
+
1,
|
| 162 |
+
1,
|
| 163 |
+
1,
|
| 164 |
+
1,
|
| 165 |
+
1,
|
| 166 |
+
1,
|
| 167 |
+
1,
|
| 168 |
+
1,
|
| 169 |
+
1,
|
| 170 |
+
1,
|
| 171 |
+
1,
|
| 172 |
+
1,
|
| 173 |
+
1,
|
| 174 |
+
1,
|
| 175 |
+
1,
|
| 176 |
+
1,
|
| 177 |
+
1,
|
| 178 |
+
1,
|
| 179 |
+
1,
|
| 180 |
+
1,
|
| 181 |
+
1,
|
| 182 |
+
1,
|
| 183 |
+
1
|
| 184 |
+
],
|
| 185 |
+
"n_group": 1,
|
| 186 |
+
"n_routed_experts": 256,
|
| 187 |
+
"n_shared_experts": null,
|
| 188 |
+
"norm_topk_prob": true,
|
| 189 |
+
"num_attention_heads": 64,
|
| 190 |
+
"num_experts_per_tok": 8,
|
| 191 |
+
"num_hidden_layers": 48,
|
| 192 |
+
"num_key_value_heads": 4,
|
| 193 |
+
"pad_token_id": 151643,
|
| 194 |
+
"partial_rotary_factor": 0.334,
|
| 195 |
+
"rope_parameters": {
|
| 196 |
+
"rope_type": "default",
|
| 197 |
+
"type": "default"
|
| 198 |
+
},
|
| 199 |
+
"rope_theta": 10000000,
|
| 200 |
+
"routed_scaling_factor": 1.0,
|
| 201 |
+
"scoring_func": "sigmoid",
|
| 202 |
+
"sliding_window": 128,
|
| 203 |
+
"sliding_window_size": 128,
|
| 204 |
+
"swa_head_dim": 192,
|
| 205 |
+
"swa_num_attention_heads": 64,
|
| 206 |
+
"swa_num_key_value_heads": 8,
|
| 207 |
+
"swa_rope_theta": 10000,
|
| 208 |
+
"swa_v_head_dim": 128,
|
| 209 |
+
"tie_word_embeddings": false,
|
| 210 |
+
"topk_group": 1,
|
| 211 |
+
"topk_method": "noaux_tc",
|
| 212 |
+
"transformers_version": "5.17.0",
|
| 213 |
+
"use_cache": true,
|
| 214 |
+
"v_head_dim": 128,
|
| 215 |
+
"vocab_size": 152576,
|
| 216 |
+
"quantization_config": {
|
| 217 |
+
"config_groups": {
|
| 218 |
+
"group_0": {
|
| 219 |
+
"input_activations": {
|
| 220 |
+
"dynamic": false,
|
| 221 |
+
"num_bits": 4,
|
| 222 |
+
"type": "float",
|
| 223 |
+
"group_size": 16
|
| 224 |
+
},
|
| 225 |
+
"weights": {
|
| 226 |
+
"dynamic": false,
|
| 227 |
+
"num_bits": 4,
|
| 228 |
+
"type": "float",
|
| 229 |
+
"group_size": 16
|
| 230 |
+
},
|
| 231 |
+
"targets": [
|
| 232 |
+
"Linear"
|
| 233 |
+
]
|
| 234 |
+
}
|
| 235 |
+
},
|
| 236 |
+
"ignore": [
|
| 237 |
+
"lm_head",
|
| 238 |
+
"model.embed_tokens",
|
| 239 |
+
"model.layers.0*",
|
| 240 |
+
"model.layers.1.mlp.gate",
|
| 241 |
+
"model.layers.1.self_attn*",
|
| 242 |
+
"model.layers.2.mlp.gate",
|
| 243 |
+
"model.layers.2.self_attn*",
|
| 244 |
+
"model.layers.3.mlp.gate",
|
| 245 |
+
"model.layers.3.self_attn*",
|
| 246 |
+
"model.layers.4.mlp.gate",
|
| 247 |
+
"model.layers.4.self_attn*",
|
| 248 |
+
"model.layers.5.mlp.gate",
|
| 249 |
+
"model.layers.5.self_attn*",
|
| 250 |
+
"model.layers.6.mlp.gate",
|
| 251 |
+
"model.layers.6.self_attn*",
|
| 252 |
+
"model.layers.7.mlp.gate",
|
| 253 |
+
"model.layers.7.self_attn*",
|
| 254 |
+
"model.layers.8.mlp.gate",
|
| 255 |
+
"model.layers.8.self_attn*",
|
| 256 |
+
"model.layers.9.mlp.gate",
|
| 257 |
+
"model.layers.9.self_attn*",
|
| 258 |
+
"model.layers.10.mlp.gate",
|
| 259 |
+
"model.layers.10.self_attn*",
|
| 260 |
+
"model.layers.11.mlp.gate",
|
| 261 |
+
"model.layers.11.self_attn*",
|
| 262 |
+
"model.layers.12.mlp.gate",
|
| 263 |
+
"model.layers.12.self_attn*",
|
| 264 |
+
"model.layers.13.mlp.gate",
|
| 265 |
+
"model.layers.13.self_attn*",
|
| 266 |
+
"model.layers.14.mlp.gate",
|
| 267 |
+
"model.layers.14.self_attn*",
|
| 268 |
+
"model.layers.15.mlp.gate",
|
| 269 |
+
"model.layers.15.self_attn*",
|
| 270 |
+
"model.layers.16.mlp.gate",
|
| 271 |
+
"model.layers.16.self_attn*",
|
| 272 |
+
"model.layers.17.mlp.gate",
|
| 273 |
+
"model.layers.17.self_attn*",
|
| 274 |
+
"model.layers.18.mlp.gate",
|
| 275 |
+
"model.layers.18.self_attn*",
|
| 276 |
+
"model.layers.19.mlp.gate",
|
| 277 |
+
"model.layers.19.self_attn*",
|
| 278 |
+
"model.layers.20.mlp.gate",
|
| 279 |
+
"model.layers.20.self_attn*",
|
| 280 |
+
"model.layers.21.mlp.gate",
|
| 281 |
+
"model.layers.21.self_attn*",
|
| 282 |
+
"model.layers.22.mlp.gate",
|
| 283 |
+
"model.layers.22.self_attn*",
|
| 284 |
+
"model.layers.23.mlp.gate",
|
| 285 |
+
"model.layers.23.self_attn*",
|
| 286 |
+
"model.layers.24.mlp.gate",
|
| 287 |
+
"model.layers.24.self_attn*",
|
| 288 |
+
"model.layers.25.mlp.gate",
|
| 289 |
+
"model.layers.25.self_attn*",
|
| 290 |
+
"model.layers.26.mlp.gate",
|
| 291 |
+
"model.layers.26.self_attn*",
|
| 292 |
+
"model.layers.27.mlp.gate",
|
| 293 |
+
"model.layers.27.self_attn*",
|
| 294 |
+
"model.layers.28.mlp.gate",
|
| 295 |
+
"model.layers.28.self_attn*",
|
| 296 |
+
"model.layers.29.mlp.gate",
|
| 297 |
+
"model.layers.29.self_attn*",
|
| 298 |
+
"model.layers.30.mlp.gate",
|
| 299 |
+
"model.layers.30.self_attn*",
|
| 300 |
+
"model.layers.31.mlp.gate",
|
| 301 |
+
"model.layers.31.self_attn*",
|
| 302 |
+
"model.layers.32.mlp.gate",
|
| 303 |
+
"model.layers.32.self_attn*",
|
| 304 |
+
"model.layers.33.mlp.gate",
|
| 305 |
+
"model.layers.33.self_attn*",
|
| 306 |
+
"model.layers.34.mlp.gate",
|
| 307 |
+
"model.layers.34.self_attn*",
|
| 308 |
+
"model.layers.35.mlp.gate",
|
| 309 |
+
"model.layers.35.self_attn*",
|
| 310 |
+
"model.layers.36.mlp.gate",
|
| 311 |
+
"model.layers.36.self_attn*",
|
| 312 |
+
"model.layers.37.mlp.gate",
|
| 313 |
+
"model.layers.37.self_attn*",
|
| 314 |
+
"model.layers.38.mlp.gate",
|
| 315 |
+
"model.layers.38.self_attn*",
|
| 316 |
+
"model.layers.39.mlp.gate",
|
| 317 |
+
"model.layers.39.self_attn*",
|
| 318 |
+
"model.layers.40.mlp.gate",
|
| 319 |
+
"model.layers.40.self_attn*",
|
| 320 |
+
"model.layers.41.mlp.gate",
|
| 321 |
+
"model.layers.41.self_attn*",
|
| 322 |
+
"model.layers.42.mlp.gate",
|
| 323 |
+
"model.layers.42.self_attn*",
|
| 324 |
+
"model.layers.43.mlp.gate",
|
| 325 |
+
"model.layers.43.self_attn*",
|
| 326 |
+
"model.layers.44.mlp.gate",
|
| 327 |
+
"model.layers.44.self_attn*",
|
| 328 |
+
"model.layers.45.mlp.gate",
|
| 329 |
+
"model.layers.45.self_attn*",
|
| 330 |
+
"model.layers.46.mlp.gate",
|
| 331 |
+
"model.layers.46.self_attn*",
|
| 332 |
+
"model.layers.47.mlp.gate",
|
| 333 |
+
"model.layers.47.self_attn*"
|
| 334 |
+
],
|
| 335 |
+
"quant_algo": "NVFP4",
|
| 336 |
+
"producer": {
|
| 337 |
+
"name": "modelopt",
|
| 338 |
+
"version": "0.0.1.dev1+g23355eda9"
|
| 339 |
+
},
|
| 340 |
+
"quant_method": "modelopt"
|
| 341 |
+
}
|
| 342 |
+
}
|
configuration_naive_n05_flash.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2026 Naive AI.
|
| 2 |
+
# Copyright 2026 The HuggingFace Inc. team.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
|
| 16 |
+
from transformers.configuration_utils import PretrainedConfig
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class NaiveN05FlashConfig(PretrainedConfig):
|
| 20 |
+
model_type = "naive_n05_flash"
|
| 21 |
+
keys_to_ignore_at_inference = ["past_key_values"]
|
| 22 |
+
attribute_map = {"num_local_experts": "n_routed_experts"}
|
| 23 |
+
|
| 24 |
+
def __init__(
|
| 25 |
+
self,
|
| 26 |
+
vocab_size: int = 152576,
|
| 27 |
+
hidden_size: int = 4096,
|
| 28 |
+
intermediate_size: int = 16384,
|
| 29 |
+
num_hidden_layers: int = 48,
|
| 30 |
+
num_attention_heads: int = 64,
|
| 31 |
+
num_key_value_heads: int = 4,
|
| 32 |
+
head_dim: int = 192,
|
| 33 |
+
v_head_dim: int = 128,
|
| 34 |
+
swa_num_attention_heads: int = 64,
|
| 35 |
+
swa_num_key_value_heads: int = 8,
|
| 36 |
+
swa_head_dim: int = 192,
|
| 37 |
+
swa_v_head_dim: int = 128,
|
| 38 |
+
hidden_act: str = "silu",
|
| 39 |
+
max_position_embeddings: int = 1048576,
|
| 40 |
+
initializer_range: float = 0.02,
|
| 41 |
+
layernorm_epsilon: float = 1e-5,
|
| 42 |
+
rope_theta: float = 10000000.0,
|
| 43 |
+
swa_rope_theta: float = 10000.0,
|
| 44 |
+
partial_rotary_factor: float = 0.334,
|
| 45 |
+
sliding_window: int = 128,
|
| 46 |
+
hybrid_layer_pattern: list[int] | None = None,
|
| 47 |
+
attention_bias: bool = False,
|
| 48 |
+
attention_projection_layout: str = "split",
|
| 49 |
+
attention_value_scale: float | None = 0.707,
|
| 50 |
+
add_full_attention_sink_bias: bool = False,
|
| 51 |
+
add_swa_attention_sink_bias: bool = True,
|
| 52 |
+
n_routed_experts: int = 256,
|
| 53 |
+
moe_intermediate_size: int = 2048,
|
| 54 |
+
num_experts_per_tok: int = 8,
|
| 55 |
+
routed_scaling_factor: float | None = 1.0,
|
| 56 |
+
scoring_func: str = "sigmoid",
|
| 57 |
+
topk_method: str = "noaux_tc",
|
| 58 |
+
n_group: int = 1,
|
| 59 |
+
topk_group: int = 1,
|
| 60 |
+
norm_topk_prob: bool = True,
|
| 61 |
+
moe_layer_freq: list[int] | None = None,
|
| 62 |
+
enable_dsa: bool = True,
|
| 63 |
+
index_top_k: int = 2048,
|
| 64 |
+
index_head_dim: int = 128,
|
| 65 |
+
index_n_heads: int = 16,
|
| 66 |
+
index_n_kv_heads: int = 1,
|
| 67 |
+
indexer_activation_dtype: str = "fp8_e4m3",
|
| 68 |
+
use_cache: bool = True,
|
| 69 |
+
tie_word_embeddings: bool = False,
|
| 70 |
+
pad_token_id: int | None = 151643,
|
| 71 |
+
eos_token_id: int | list[int] | None = 151645,
|
| 72 |
+
**kwargs,
|
| 73 |
+
) -> None:
|
| 74 |
+
self.vocab_size = vocab_size
|
| 75 |
+
self.hidden_size = hidden_size
|
| 76 |
+
self.intermediate_size = intermediate_size
|
| 77 |
+
self.num_hidden_layers = num_hidden_layers
|
| 78 |
+
self.num_attention_heads = num_attention_heads
|
| 79 |
+
self.num_key_value_heads = num_key_value_heads
|
| 80 |
+
self.head_dim = head_dim
|
| 81 |
+
self.v_head_dim = v_head_dim
|
| 82 |
+
self.swa_num_attention_heads = swa_num_attention_heads
|
| 83 |
+
self.swa_num_key_value_heads = swa_num_key_value_heads
|
| 84 |
+
self.swa_head_dim = swa_head_dim
|
| 85 |
+
self.swa_v_head_dim = swa_v_head_dim
|
| 86 |
+
self.hidden_act = hidden_act
|
| 87 |
+
self.max_position_embeddings = max_position_embeddings
|
| 88 |
+
self.initializer_range = initializer_range
|
| 89 |
+
self.layernorm_epsilon = layernorm_epsilon
|
| 90 |
+
self.rope_theta = rope_theta
|
| 91 |
+
self.swa_rope_theta = swa_rope_theta
|
| 92 |
+
self.partial_rotary_factor = partial_rotary_factor
|
| 93 |
+
self.sliding_window = sliding_window
|
| 94 |
+
self.hybrid_layer_pattern = hybrid_layer_pattern or [
|
| 95 |
+
int(i != 0 and i % 6 != 5) for i in range(num_hidden_layers)
|
| 96 |
+
]
|
| 97 |
+
self.attention_bias = attention_bias
|
| 98 |
+
self.attention_projection_layout = attention_projection_layout
|
| 99 |
+
self.attention_value_scale = attention_value_scale
|
| 100 |
+
self.add_full_attention_sink_bias = add_full_attention_sink_bias
|
| 101 |
+
self.add_swa_attention_sink_bias = add_swa_attention_sink_bias
|
| 102 |
+
self.n_routed_experts = n_routed_experts
|
| 103 |
+
self.moe_intermediate_size = moe_intermediate_size
|
| 104 |
+
self.num_experts_per_tok = num_experts_per_tok
|
| 105 |
+
self.routed_scaling_factor = routed_scaling_factor or 1.0
|
| 106 |
+
self.scoring_func = scoring_func
|
| 107 |
+
self.topk_method = topk_method
|
| 108 |
+
self.n_group = n_group
|
| 109 |
+
self.topk_group = topk_group
|
| 110 |
+
self.norm_topk_prob = norm_topk_prob
|
| 111 |
+
self.moe_layer_freq = moe_layer_freq or ([0] + [1] * (num_hidden_layers - 1))
|
| 112 |
+
self.enable_dsa = enable_dsa
|
| 113 |
+
self.index_top_k = index_top_k
|
| 114 |
+
self.index_head_dim = index_head_dim
|
| 115 |
+
self.index_n_heads = index_n_heads
|
| 116 |
+
self.index_n_kv_heads = index_n_kv_heads
|
| 117 |
+
self.indexer_activation_dtype = indexer_activation_dtype
|
| 118 |
+
self.use_cache = use_cache
|
| 119 |
+
super().__init__(
|
| 120 |
+
tie_word_embeddings=tie_word_embeddings, pad_token_id=pad_token_id, eos_token_id=eos_token_id, **kwargs
|
| 121 |
+
)
|
| 122 |
+
self.validate()
|
| 123 |
+
|
| 124 |
+
def validate(self):
|
| 125 |
+
if self.attention_projection_layout != "split" or self.index_n_kv_heads != 1:
|
| 126 |
+
raise ValueError("NaiveN05Flash requires split Q/K/V and one indexer KV head")
|
| 127 |
+
if not self.enable_dsa or self.index_top_k <= 0:
|
| 128 |
+
raise ValueError("NaiveN05Flash requires DSA with a positive index_top_k")
|
| 129 |
+
if self.indexer_activation_dtype not in ("bf16", "fp8_e4m3"):
|
| 130 |
+
raise ValueError("indexer_activation_dtype must be bf16 or fp8_e4m3")
|
| 131 |
+
if self.scoring_func != "sigmoid" or self.topk_method != "noaux_tc":
|
| 132 |
+
raise ValueError("NaiveN05Flash requires sigmoid routing with correction bias")
|
| 133 |
+
if self.n_group != 1 or self.topk_group != 1:
|
| 134 |
+
raise ValueError("NaiveN05Flash uses one expert group")
|
| 135 |
+
for prefix in ("", "swa_"):
|
| 136 |
+
heads = getattr(self, prefix + "num_attention_heads")
|
| 137 |
+
kv_heads = getattr(self, prefix + "num_key_value_heads")
|
| 138 |
+
head_dim = getattr(self, prefix + "head_dim")
|
| 139 |
+
rotary_dim = int(head_dim * self.partial_rotary_factor)
|
| 140 |
+
if kv_heads <= 0 or heads % kv_heads or rotary_dim % 2 or not 0 < rotary_dim <= head_dim:
|
| 141 |
+
raise ValueError("Invalid attention head or rotary dimensions")
|
| 142 |
+
if int(self.head_dim * self.partial_rotary_factor) > self.index_head_dim:
|
| 143 |
+
raise ValueError("Indexer head dimension must cover the rotary dimension")
|
| 144 |
+
if self._attn_implementation not in (None, "eager"):
|
| 145 |
+
raise ValueError("NaiveN05Flash supports eager attention only")
|
| 146 |
+
if len(self.hybrid_layer_pattern) != self.num_hidden_layers:
|
| 147 |
+
raise ValueError("hybrid_layer_pattern must contain one entry per layer")
|
| 148 |
+
if len(self.moe_layer_freq) != self.num_hidden_layers:
|
| 149 |
+
raise ValueError("moe_layer_freq must contain one entry per layer")
|
| 150 |
+
self.layer_types = [
|
| 151 |
+
"sliding_attention" if is_swa else "deepseek_sparse_attention" for is_swa in self.hybrid_layer_pattern
|
| 152 |
+
]
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
__all__ = ["NaiveN05FlashConfig"]
|
generation_config.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"do_sample": true,
|
| 3 |
+
"temperature": 1.0,
|
| 4 |
+
"top_p": 0.95,
|
| 5 |
+
"repetition_penalty": 1.0,
|
| 6 |
+
"eos_token_id": 151645,
|
| 7 |
+
"pad_token_id": 151643,
|
| 8 |
+
"max_new_tokens": 131072
|
| 9 |
+
}
|
hf_quant_config.json
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"producer": {
|
| 3 |
+
"name": "modelopt",
|
| 4 |
+
"version": "0.0.1.dev1+g23355eda9"
|
| 5 |
+
},
|
| 6 |
+
"quantization": {
|
| 7 |
+
"quant_algo": "NVFP4",
|
| 8 |
+
"kv_cache_quant_algo": null,
|
| 9 |
+
"group_size": 16,
|
| 10 |
+
"exclude_modules": [
|
| 11 |
+
"lm_head",
|
| 12 |
+
"model.embed_tokens",
|
| 13 |
+
"model.layers.0*",
|
| 14 |
+
"model.layers.1.mlp.gate",
|
| 15 |
+
"model.layers.1.self_attn*",
|
| 16 |
+
"model.layers.2.mlp.gate",
|
| 17 |
+
"model.layers.2.self_attn*",
|
| 18 |
+
"model.layers.3.mlp.gate",
|
| 19 |
+
"model.layers.3.self_attn*",
|
| 20 |
+
"model.layers.4.mlp.gate",
|
| 21 |
+
"model.layers.4.self_attn*",
|
| 22 |
+
"model.layers.5.mlp.gate",
|
| 23 |
+
"model.layers.5.self_attn*",
|
| 24 |
+
"model.layers.6.mlp.gate",
|
| 25 |
+
"model.layers.6.self_attn*",
|
| 26 |
+
"model.layers.7.mlp.gate",
|
| 27 |
+
"model.layers.7.self_attn*",
|
| 28 |
+
"model.layers.8.mlp.gate",
|
| 29 |
+
"model.layers.8.self_attn*",
|
| 30 |
+
"model.layers.9.mlp.gate",
|
| 31 |
+
"model.layers.9.self_attn*",
|
| 32 |
+
"model.layers.10.mlp.gate",
|
| 33 |
+
"model.layers.10.self_attn*",
|
| 34 |
+
"model.layers.11.mlp.gate",
|
| 35 |
+
"model.layers.11.self_attn*",
|
| 36 |
+
"model.layers.12.mlp.gate",
|
| 37 |
+
"model.layers.12.self_attn*",
|
| 38 |
+
"model.layers.13.mlp.gate",
|
| 39 |
+
"model.layers.13.self_attn*",
|
| 40 |
+
"model.layers.14.mlp.gate",
|
| 41 |
+
"model.layers.14.self_attn*",
|
| 42 |
+
"model.layers.15.mlp.gate",
|
| 43 |
+
"model.layers.15.self_attn*",
|
| 44 |
+
"model.layers.16.mlp.gate",
|
| 45 |
+
"model.layers.16.self_attn*",
|
| 46 |
+
"model.layers.17.mlp.gate",
|
| 47 |
+
"model.layers.17.self_attn*",
|
| 48 |
+
"model.layers.18.mlp.gate",
|
| 49 |
+
"model.layers.18.self_attn*",
|
| 50 |
+
"model.layers.19.mlp.gate",
|
| 51 |
+
"model.layers.19.self_attn*",
|
| 52 |
+
"model.layers.20.mlp.gate",
|
| 53 |
+
"model.layers.20.self_attn*",
|
| 54 |
+
"model.layers.21.mlp.gate",
|
| 55 |
+
"model.layers.21.self_attn*",
|
| 56 |
+
"model.layers.22.mlp.gate",
|
| 57 |
+
"model.layers.22.self_attn*",
|
| 58 |
+
"model.layers.23.mlp.gate",
|
| 59 |
+
"model.layers.23.self_attn*",
|
| 60 |
+
"model.layers.24.mlp.gate",
|
| 61 |
+
"model.layers.24.self_attn*",
|
| 62 |
+
"model.layers.25.mlp.gate",
|
| 63 |
+
"model.layers.25.self_attn*",
|
| 64 |
+
"model.layers.26.mlp.gate",
|
| 65 |
+
"model.layers.26.self_attn*",
|
| 66 |
+
"model.layers.27.mlp.gate",
|
| 67 |
+
"model.layers.27.self_attn*",
|
| 68 |
+
"model.layers.28.mlp.gate",
|
| 69 |
+
"model.layers.28.self_attn*",
|
| 70 |
+
"model.layers.29.mlp.gate",
|
| 71 |
+
"model.layers.29.self_attn*",
|
| 72 |
+
"model.layers.30.mlp.gate",
|
| 73 |
+
"model.layers.30.self_attn*",
|
| 74 |
+
"model.layers.31.mlp.gate",
|
| 75 |
+
"model.layers.31.self_attn*",
|
| 76 |
+
"model.layers.32.mlp.gate",
|
| 77 |
+
"model.layers.32.self_attn*",
|
| 78 |
+
"model.layers.33.mlp.gate",
|
| 79 |
+
"model.layers.33.self_attn*",
|
| 80 |
+
"model.layers.34.mlp.gate",
|
| 81 |
+
"model.layers.34.self_attn*",
|
| 82 |
+
"model.layers.35.mlp.gate",
|
| 83 |
+
"model.layers.35.self_attn*",
|
| 84 |
+
"model.layers.36.mlp.gate",
|
| 85 |
+
"model.layers.36.self_attn*",
|
| 86 |
+
"model.layers.37.mlp.gate",
|
| 87 |
+
"model.layers.37.self_attn*",
|
| 88 |
+
"model.layers.38.mlp.gate",
|
| 89 |
+
"model.layers.38.self_attn*",
|
| 90 |
+
"model.layers.39.mlp.gate",
|
| 91 |
+
"model.layers.39.self_attn*",
|
| 92 |
+
"model.layers.40.mlp.gate",
|
| 93 |
+
"model.layers.40.self_attn*",
|
| 94 |
+
"model.layers.41.mlp.gate",
|
| 95 |
+
"model.layers.41.self_attn*",
|
| 96 |
+
"model.layers.42.mlp.gate",
|
| 97 |
+
"model.layers.42.self_attn*",
|
| 98 |
+
"model.layers.43.mlp.gate",
|
| 99 |
+
"model.layers.43.self_attn*",
|
| 100 |
+
"model.layers.44.mlp.gate",
|
| 101 |
+
"model.layers.44.self_attn*",
|
| 102 |
+
"model.layers.45.mlp.gate",
|
| 103 |
+
"model.layers.45.self_attn*",
|
| 104 |
+
"model.layers.46.mlp.gate",
|
| 105 |
+
"model.layers.46.self_attn*",
|
| 106 |
+
"model.layers.47.mlp.gate",
|
| 107 |
+
"model.layers.47.self_attn*"
|
| 108 |
+
]
|
| 109 |
+
}
|
| 110 |
+
}
|
model.safetensors.index.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b989f8e0c01e2b54f46efcd3d134b53b23c59c8faba37df1d8a6a52a0baccdec
|
| 3 |
+
size 13388642
|
modeling_naive_n05_flash.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2026 Naive AI.
|
| 2 |
+
# Copyright 2026 The HuggingFace Inc. team.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
|
| 16 |
+
from copy import copy
|
| 17 |
+
|
| 18 |
+
import torch
|
| 19 |
+
from torch import nn
|
| 20 |
+
from transformers.cache_utils import DynamicCache
|
| 21 |
+
from transformers.conversion_mapping import get_checkpoint_conversion_mapping, register_checkpoint_conversion_mapping
|
| 22 |
+
from transformers.generation import GenerationMixin
|
| 23 |
+
from transformers.modeling_outputs import CausalLMOutputWithPast
|
| 24 |
+
from transformers.modeling_utils import PreTrainedModel
|
| 25 |
+
from transformers.models.deepseek_v3.modeling_deepseek_v3 import DeepseekV3Experts, DeepseekV3TopkRouter
|
| 26 |
+
from transformers.models.deepseek_v3.modeling_deepseek_v3 import DeepseekV3MLP as NaiveN05FlashMLP
|
| 27 |
+
from transformers.models.gpt_neox.modeling_gpt_neox import GPTNeoXRotaryEmbedding as NaiveN05FlashRotaryEmbedding
|
| 28 |
+
from transformers.models.gpt_neox.modeling_gpt_neox import apply_rotary_pos_emb
|
| 29 |
+
from transformers.models.llama.modeling_llama import LlamaRMSNorm as NaiveN05FlashRMSNorm
|
| 30 |
+
from transformers.models.llama.modeling_llama import repeat_kv
|
| 31 |
+
|
| 32 |
+
from .configuration_naive_n05_flash import NaiveN05FlashConfig
|
| 33 |
+
|
| 34 |
+
# Fuse experts weights
|
| 35 |
+
# mlp.experts.{i}.{gate,up,down}_proj.weight[_scale_inv] -> mlp.experts.{gate,up,down}_proj.weight[_scale_inv]
|
| 36 |
+
register_checkpoint_conversion_mapping("naive_n05_flash", get_checkpoint_conversion_mapping("deepseek_v3"), overwrite=True)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def round_indexer_fp8(states):
|
| 40 |
+
states = states.float()
|
| 41 |
+
scale = states.abs().amax(dim=-1, keepdim=True).clamp_min(1e-4) / 448.0
|
| 42 |
+
return (states / scale).clamp(-448, 448).to(torch.float8_e4m3fn).float() * scale
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class NaiveN05FlashMoE(nn.Module):
|
| 46 |
+
"""DeepSeek-V3-style routed experts without a shared expert."""
|
| 47 |
+
|
| 48 |
+
def __init__(self, config):
|
| 49 |
+
super().__init__()
|
| 50 |
+
self.experts = DeepseekV3Experts(config)
|
| 51 |
+
self.gate = DeepseekV3TopkRouter(config)
|
| 52 |
+
|
| 53 |
+
def forward(self, states):
|
| 54 |
+
original_shape = states.shape
|
| 55 |
+
_, topk_weights, topk_indices = self.gate(states)
|
| 56 |
+
states = states.view(-1, states.shape[-1])
|
| 57 |
+
states = self.experts(states, topk_indices, topk_weights)
|
| 58 |
+
return states.view(*original_shape)
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
class NaiveN05FlashIndexer(nn.Module):
|
| 62 |
+
def __init__(self, config, layer_idx):
|
| 63 |
+
super().__init__()
|
| 64 |
+
self.config = config
|
| 65 |
+
self.layer_idx = layer_idx
|
| 66 |
+
self.wq = nn.Linear(config.hidden_size, config.index_n_heads * config.index_head_dim, bias=False)
|
| 67 |
+
self.wk = nn.Linear(config.hidden_size, config.index_head_dim, bias=False)
|
| 68 |
+
self.k_norm = nn.LayerNorm(config.index_head_dim, eps=1e-5)
|
| 69 |
+
self.weights_proj = nn.Linear(config.hidden_size, config.index_n_heads, bias=False)
|
| 70 |
+
|
| 71 |
+
def forward(self, states, position_embeddings, past_key_values=None):
|
| 72 |
+
c = self.config
|
| 73 |
+
batch, length, _ = states.shape
|
| 74 |
+
query = self.wq(states).view(batch, length, c.index_n_heads, c.index_head_dim).transpose(1, 2)
|
| 75 |
+
key = self.k_norm(self.wk(states)).unsqueeze(1)
|
| 76 |
+
query, key = apply_rotary_pos_emb(query, key, *position_embeddings)
|
| 77 |
+
if c.indexer_activation_dtype == "fp8_e4m3":
|
| 78 |
+
query, key = round_indexer_fp8(query), round_indexer_fp8(key)
|
| 79 |
+
if past_key_values is not None:
|
| 80 |
+
key = past_key_values.update_indexer(key.squeeze(1), self.layer_idx).unsqueeze(1)
|
| 81 |
+
scores = (query.float() @ key.float().transpose(-1, -2)).relu()
|
| 82 |
+
weights = self.weights_proj(states) * c.index_n_heads**-0.5
|
| 83 |
+
return (scores * weights.transpose(1, 2).unsqueeze(-1).float()).sum(dim=1)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
class NaiveN05FlashAttention(nn.Module):
|
| 87 |
+
def __init__(self, config, layer_idx):
|
| 88 |
+
super().__init__()
|
| 89 |
+
self.config = config
|
| 90 |
+
self.layer_idx = layer_idx
|
| 91 |
+
self.is_swa = bool(config.hybrid_layer_pattern[layer_idx])
|
| 92 |
+
prefix = "swa_" if self.is_swa else ""
|
| 93 |
+
self.heads = getattr(config, prefix + "num_attention_heads")
|
| 94 |
+
self.kv_heads = getattr(config, prefix + "num_key_value_heads")
|
| 95 |
+
self.head_dim = getattr(config, prefix + "head_dim")
|
| 96 |
+
self.v_dim = getattr(config, prefix + "v_head_dim")
|
| 97 |
+
rope_config = copy(config)
|
| 98 |
+
rope_config.head_dim = self.head_dim
|
| 99 |
+
rope_config.rope_parameters = {
|
| 100 |
+
"rope_type": "default",
|
| 101 |
+
"rope_theta": getattr(config, prefix + "rope_theta"),
|
| 102 |
+
"partial_rotary_factor": config.partial_rotary_factor,
|
| 103 |
+
}
|
| 104 |
+
self.rotary_emb = NaiveN05FlashRotaryEmbedding(rope_config)
|
| 105 |
+
self.q_proj = nn.Linear(config.hidden_size, self.heads * self.head_dim, bias=config.attention_bias)
|
| 106 |
+
self.k_proj = nn.Linear(
|
| 107 |
+
config.hidden_size,
|
| 108 |
+
self.kv_heads * self.head_dim,
|
| 109 |
+
bias=config.attention_bias,
|
| 110 |
+
)
|
| 111 |
+
self.v_proj = nn.Linear(config.hidden_size, self.kv_heads * self.v_dim, bias=config.attention_bias)
|
| 112 |
+
self.o_proj = nn.Linear(self.heads * self.v_dim, config.hidden_size, bias=False)
|
| 113 |
+
self.indexer = None if self.is_swa else NaiveN05FlashIndexer(config, layer_idx)
|
| 114 |
+
sink = config.add_swa_attention_sink_bias if self.is_swa else config.add_full_attention_sink_bias
|
| 115 |
+
self.attention_sink_bias = nn.Parameter(torch.zeros(self.heads), requires_grad=False) if sink else None
|
| 116 |
+
|
| 117 |
+
def forward(self, states, positions, allowed, past_key_values=None):
|
| 118 |
+
batch, length, _ = states.shape
|
| 119 |
+
past_length = 0 if past_key_values is None else past_key_values.get_seq_length(self.layer_idx)
|
| 120 |
+
key_offset = 0 if past_key_values is None else past_key_values.get_mask_sizes(length, self.layer_idx)[1]
|
| 121 |
+
query = self.q_proj(states).view(batch, length, self.heads, self.head_dim).transpose(1, 2)
|
| 122 |
+
key = self.k_proj(states).view(batch, length, self.kv_heads, self.head_dim).transpose(1, 2)
|
| 123 |
+
value = self.v_proj(states).view(batch, length, self.kv_heads, self.v_dim).transpose(1, 2)
|
| 124 |
+
position_embeddings = self.rotary_emb(states, positions)
|
| 125 |
+
query, key = apply_rotary_pos_emb(query, key, *position_embeddings)
|
| 126 |
+
if past_key_values is not None:
|
| 127 |
+
key, value = past_key_values.update(key, value, self.layer_idx)
|
| 128 |
+
key_length = key.shape[-2]
|
| 129 |
+
allowed = allowed[..., key_offset : key_offset + key_length]
|
| 130 |
+
if self.is_swa:
|
| 131 |
+
query_offsets = past_length + torch.arange(length, device=states.device)
|
| 132 |
+
key_offsets = key_offset + torch.arange(key_length, device=states.device)
|
| 133 |
+
allowed = allowed & (query_offsets[:, None] - key_offsets[None, :] < self.config.sliding_window)
|
| 134 |
+
else:
|
| 135 |
+
scores = self.indexer(states, position_embeddings, past_key_values).masked_fill(~allowed, -torch.inf)
|
| 136 |
+
# Stable ties keep padding from changing which equal-score keys win.
|
| 137 |
+
selected = scores.argsort(dim=-1, descending=True, stable=True)[..., : self.config.index_top_k]
|
| 138 |
+
allowed = allowed & torch.zeros_like(scores, dtype=torch.bool).scatter(-1, selected, True)
|
| 139 |
+
key = repeat_kv(key, self.heads // self.kv_heads)
|
| 140 |
+
value = repeat_kv(value, self.heads // self.kv_heads)
|
| 141 |
+
if self.config.attention_value_scale is not None:
|
| 142 |
+
value = value * self.config.attention_value_scale
|
| 143 |
+
logits = (query @ key.transpose(-1, -2)) * self.head_dim**-0.5
|
| 144 |
+
logits = logits.masked_fill(~allowed[:, None], -torch.inf)
|
| 145 |
+
if self.attention_sink_bias is not None:
|
| 146 |
+
sink = self.attention_sink_bias[None, :, None, None].expand(batch, -1, length, -1)
|
| 147 |
+
logits = torch.cat((logits, sink), dim=-1)
|
| 148 |
+
probabilities = logits.float().softmax(-1).nan_to_num(0.0)[..., :key_length].to(value.dtype)
|
| 149 |
+
output = (probabilities @ value).transpose(1, 2).reshape(batch, length, -1)
|
| 150 |
+
return self.o_proj(output)
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
class NaiveN05FlashDecoderLayer(nn.Module):
|
| 154 |
+
def __init__(self, config, layer_idx):
|
| 155 |
+
super().__init__()
|
| 156 |
+
self.self_attn = NaiveN05FlashAttention(config, layer_idx)
|
| 157 |
+
self.mlp = NaiveN05FlashMoE(config) if config.moe_layer_freq[layer_idx] else NaiveN05FlashMLP(config)
|
| 158 |
+
self.input_layernorm = NaiveN05FlashRMSNorm(config.hidden_size, config.layernorm_epsilon)
|
| 159 |
+
self.post_attention_layernorm = NaiveN05FlashRMSNorm(config.hidden_size, config.layernorm_epsilon)
|
| 160 |
+
|
| 161 |
+
def forward(self, states, positions, allowed, past_key_values=None):
|
| 162 |
+
states = states + self.self_attn(self.input_layernorm(states), positions, allowed, past_key_values)
|
| 163 |
+
return states + self.mlp(self.post_attention_layernorm(states))
|
| 164 |
+
|
| 165 |
+
|
| 166 |
+
class NaiveN05FlashModel(PreTrainedModel):
|
| 167 |
+
config_class = NaiveN05FlashConfig
|
| 168 |
+
base_model_prefix = "model"
|
| 169 |
+
_can_set_experts_implementation_cached_value = True
|
| 170 |
+
|
| 171 |
+
def __init__(self, config):
|
| 172 |
+
super().__init__(config)
|
| 173 |
+
self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size)
|
| 174 |
+
self.layers = nn.ModuleList([NaiveN05FlashDecoderLayer(config, i) for i in range(config.num_hidden_layers)])
|
| 175 |
+
self.norm = NaiveN05FlashRMSNorm(config.hidden_size, config.layernorm_epsilon)
|
| 176 |
+
|
| 177 |
+
def forward(self, states, positions, allowed, past_key_values=None):
|
| 178 |
+
for layer in self.layers:
|
| 179 |
+
states = layer(states, positions, allowed, past_key_values)
|
| 180 |
+
return self.norm(states)
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
class NaiveN05FlashForCausalLM(PreTrainedModel, GenerationMixin):
|
| 184 |
+
config_class = NaiveN05FlashConfig
|
| 185 |
+
base_model_prefix = "model"
|
| 186 |
+
_no_split_modules = ["NaiveN05FlashDecoderLayer"]
|
| 187 |
+
_skip_keys_device_placement = ["past_key_values"]
|
| 188 |
+
_keep_in_fp32_modules_strict = ["mlp.gate.weight", "mlp.gate.e_score_correction_bias"]
|
| 189 |
+
_can_set_experts_implementation_cached_value = True
|
| 190 |
+
|
| 191 |
+
def __init__(self, config):
|
| 192 |
+
config.validate()
|
| 193 |
+
super().__init__(config)
|
| 194 |
+
self.model = NaiveN05FlashModel(config)
|
| 195 |
+
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
|
| 196 |
+
self.post_init()
|
| 197 |
+
self.eval().requires_grad_(False)
|
| 198 |
+
|
| 199 |
+
def get_input_embeddings(self):
|
| 200 |
+
return self.model.embed_tokens
|
| 201 |
+
|
| 202 |
+
def get_output_embeddings(self):
|
| 203 |
+
return self.lm_head
|
| 204 |
+
|
| 205 |
+
@torch.inference_mode()
|
| 206 |
+
def forward(
|
| 207 |
+
self,
|
| 208 |
+
input_ids=None,
|
| 209 |
+
attention_mask=None,
|
| 210 |
+
position_ids=None,
|
| 211 |
+
inputs_embeds=None,
|
| 212 |
+
use_cache=None,
|
| 213 |
+
past_key_values=None,
|
| 214 |
+
**kwargs,
|
| 215 |
+
):
|
| 216 |
+
use_cache = self.config.use_cache if use_cache is None else use_cache
|
| 217 |
+
if past_key_values is not None and not use_cache:
|
| 218 |
+
raise ValueError("Pass use_cache=True when providing past_key_values")
|
| 219 |
+
if use_cache and past_key_values is None:
|
| 220 |
+
past_key_values = DynamicCache(config=self.config)
|
| 221 |
+
if past_key_values is not None and not isinstance(past_key_values, DynamicCache):
|
| 222 |
+
raise ValueError("NaiveN05Flash supports DynamicCache only")
|
| 223 |
+
if (input_ids is None) == (inputs_embeds is None):
|
| 224 |
+
raise ValueError("Provide exactly one of input_ids or inputs_embeds")
|
| 225 |
+
states = self.model.embed_tokens(input_ids) if inputs_embeds is None else inputs_embeds
|
| 226 |
+
batch, length, _ = states.shape
|
| 227 |
+
past_length = 0 if past_key_values is None else past_key_values.get_seq_length()
|
| 228 |
+
total_length = past_length + length
|
| 229 |
+
if attention_mask is None:
|
| 230 |
+
attention_mask = torch.ones(batch, total_length, device=states.device, dtype=torch.bool)
|
| 231 |
+
if attention_mask.shape != (batch, total_length):
|
| 232 |
+
raise ValueError("Expected a 2-D attention_mask covering the cached prefix and new tokens")
|
| 233 |
+
if position_ids is None:
|
| 234 |
+
position_ids = (attention_mask.long().cumsum(-1) - 1).clamp_min(0)[:, -length:]
|
| 235 |
+
query_offsets = past_length + torch.arange(length, device=states.device)
|
| 236 |
+
key_offsets = torch.arange(total_length, device=states.device)
|
| 237 |
+
allowed = query_offsets[:, None] >= key_offsets[None, :]
|
| 238 |
+
allowed = allowed[None] & attention_mask[:, None].bool()
|
| 239 |
+
logits = self.lm_head(self.model(states, position_ids, allowed, past_key_values))
|
| 240 |
+
return CausalLMOutputWithPast(logits=logits, past_key_values=past_key_values)
|
| 241 |
+
|
| 242 |
+
|
| 243 |
+
__all__ = ["NaiveN05FlashForCausalLM", "NaiveN05FlashModel"]
|
quantization_provenance.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"source_repository": "NaiveAI/Naive-N0.5-Flash",
|
| 3 |
+
"source_revision": "0235b3b5ff27422b1f57cdc2acddfaf643e08356",
|
| 4 |
+
"modelopt_revision": "23355eda90a25c290f9b1fdfb928ad54caae7d10",
|
| 5 |
+
"recipe": "NVFP4 experts only; max calibration; original-precision attention, router and KV cache",
|
| 6 |
+
"calibration": {
|
| 7 |
+
"sources": [
|
| 8 |
+
{
|
| 9 |
+
"id": "ise-uiuc/Magicoder-OSS-Instruct-75K",
|
| 10 |
+
"revision": "5f839b1f368a76b161028bb9edff055db34022b2",
|
| 11 |
+
"format": "json",
|
| 12 |
+
"file": "data-oss_instruct-decontaminated.jsonl"
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"id": "HuggingFaceH4/ultrachat_200k",
|
| 16 |
+
"revision": "8049631c405ae6576f93f445c6b8166f76f5505a",
|
| 17 |
+
"format": "parquet",
|
| 18 |
+
"file": "data/train_sft-00000-of-00003-a3ecf92756993583.parquet"
|
| 19 |
+
}
|
| 20 |
+
],
|
| 21 |
+
"samples": 128,
|
| 22 |
+
"sequence_length": 4096,
|
| 23 |
+
"tokens": 524288,
|
| 24 |
+
"sha256": "19061f6f772f68b6fe9096a01376e236cf27ba03a1c58f2e36acc5f2f0cab758",
|
| 25 |
+
"packing": "Chat-formatted records concatenated with EOS, equal coding/chat token counts",
|
| 26 |
+
"shuffle_seed": 20260928,
|
| 27 |
+
"shuffle_buffer": 128
|
| 28 |
+
},
|
| 29 |
+
"runtime": "Native vLLM 0.28.0 V1 engine, Naive model plugin, TP4, paged KV/indexer cache, FlashInfer 0.7.0 B12x NVFP4 experts, single-request decode CUDA graphs",
|
| 30 |
+
"export_recovery": {
|
| 31 |
+
"calibration_layers_reused": 48,
|
| 32 |
+
"original_precision_tail_tensors": [
|
| 33 |
+
"lm_head.weight",
|
| 34 |
+
"model.embed_tokens.weight",
|
| 35 |
+
"model.norm.weight"
|
| 36 |
+
],
|
| 37 |
+
"tensor_bytes": 182547868032,
|
| 38 |
+
"reason": "Fused expert source names misidentified as unplaced by generic exporter"
|
| 39 |
+
},
|
| 40 |
+
"source_precision_audit": {
|
| 41 |
+
"passed": true,
|
| 42 |
+
"tensors_checked": 472,
|
| 43 |
+
"restored_from_source": {
|
| 44 |
+
"model-layer-00047.safetensors": [
|
| 45 |
+
"model.layers.47.mlp.gate.weight"
|
| 46 |
+
]
|
| 47 |
+
},
|
| 48 |
+
"check": "Exact source dtype, shape and SHA-256 of tensor payload"
|
| 49 |
+
},
|
| 50 |
+
"calibration_note": "Layer 47 routing was materialized in BF16 during calibration; its final checkpoint router is restored byte-for-byte from the FP32 source.",
|
| 51 |
+
"final_export_validation": {
|
| 52 |
+
"passed": true,
|
| 53 |
+
"tensor_count": 144856,
|
| 54 |
+
"packed_expert_weights": 36096,
|
| 55 |
+
"safetensor_shards": 49,
|
| 56 |
+
"tensor_bytes": 182549965184,
|
| 57 |
+
"all_source_tensors_accounted_for": true
|
| 58 |
+
},
|
| 59 |
+
"runtime_performance_validation": "validation/native-vllm-benchmark.json",
|
| 60 |
+
"runtime_build": "runtime/Dockerfile"
|
| 61 |
+
}
|
runtime-lock.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"base_image": "vllm/vllm-openai@sha256:61fc8a896b0a4fbbbdc063bc4b0dbc25ce98e02b5050c24aeb7830ac02039b14",
|
| 3 |
+
"tested_local_image_digest": "naive-n05-vllm@sha256:edc59ac2c49c6d62ee358ffd1ffb4a8b4a59b40a704e54da6286cf8b7f942511",
|
| 4 |
+
"image_note": "The tested derived image is locally built, not a public registry artifact. Build runtime/Dockerfile from this release.",
|
| 5 |
+
"runtime_source_sha256": {
|
| 6 |
+
".dockerignore": "05cc6ae53cfd6129f1d7010aa874c6cf0a6019b1adfeff3f4fab27f2d04f43ca",
|
| 7 |
+
"Dockerfile": "201fa4be561e877098945d37897cc0f7a7c9e7dd15eb4779b15830717682f101",
|
| 8 |
+
"LICENSE": "969b552eb338dc04f165177043e43d2b6daab45accc29021d77c200e3b3ba68a",
|
| 9 |
+
"LICENSE-APACHE-2.0.txt": "cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30",
|
| 10 |
+
"THIRD_PARTY_NOTICES.md": "f42c84a8c8a64b743c491d7e1d7ed1e1daa8ea4546f7ec877db30d4379974ece",
|
| 11 |
+
"pyproject.toml": "90ad59f3b03570a9bb18d5d399a721d5c5daf9e2acba2f5a38d6e44c7cb8e9d3",
|
| 12 |
+
"requirements.txt": "829ba4fbb1e769da9505c900701f439a3d2126c4c7d2d15e3b539fa37a20aa18",
|
| 13 |
+
"scripts/benchmark_stream.py": "dab13abe554c6c28f89268ee3a2cec2e6425f73aa91f18692318b76886704157",
|
| 14 |
+
"scripts/decode_kernels.py": "ea0e71f5c4fd678b5cdf423b62ad07d37bed7de5fdc2af9ee89f08856ee34d09",
|
| 15 |
+
"scripts/fused_experts.py": "f77eceec0a969eb7ff99e5177bd9d4cda1bfa3f0668ed614c060d28883f46018",
|
| 16 |
+
"scripts/nvfp4_runtime.py": "be6453ca83d8f9ec528b07f17e78a41bfdcd8859fa9ec2644b6136e7068e9a1a",
|
| 17 |
+
"scripts/preflight.py": "43ac170da1d7cf614fb5f4d7f0ee70635d2d78bd638bfb3af2322baf91a08600",
|
| 18 |
+
"scripts/safe_device_transfer.py": "61e931597e59e72ded3525976181e7164933e72f4647423c00ad2be0a57940db",
|
| 19 |
+
"scripts/validate_api.py": "82e04b0d21e9956da18930e27d35c4fc45f1a4b071bd2a19c6f62271deb74c2d",
|
| 20 |
+
"sitecustomize.py": "552485e6e5e03c72c1d8b76a43a1ede48f8283a5d1e5ab93761125ec4a2c492b",
|
| 21 |
+
"vllm_naive/__init__.py": "8a5fddf2b89a4c33b6774a3ed75004a73db990ee711b8411e8772d7f2786f679",
|
| 22 |
+
"vllm_naive/attention.py": "f3aa650b110495224338b211330f6dcb7598cbeff917e7b1dac77695234f187c",
|
| 23 |
+
"vllm_naive/model.py": "f0d5769018f8487c267d0ee6c3ba4cbf138e47d65c35c0cc0a00a95dfb69d763"
|
| 24 |
+
},
|
| 25 |
+
"versions": {
|
| 26 |
+
"vllm": "0.28.0",
|
| 27 |
+
"torch": "2.13.0+cu130",
|
| 28 |
+
"transformers": "5.17.0",
|
| 29 |
+
"accelerate": "1.15.0",
|
| 30 |
+
"tokenizers": "0.23.2",
|
| 31 |
+
"huggingface-hub": "1.33.0",
|
| 32 |
+
"safetensors": "0.8.0",
|
| 33 |
+
"flashinfer-python": "0.7.0",
|
| 34 |
+
"nvidia-cutlass-dsl": "4.6.2",
|
| 35 |
+
"triton": "3.7.1"
|
| 36 |
+
},
|
| 37 |
+
"tested_at": "2026-09-28T10:42:32.236283+00:00"
|
| 38 |
+
}
|
runtime/.dockerignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__
|
| 2 |
+
*.pyc
|
runtime/Dockerfile
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM vllm/vllm-openai@sha256:61fc8a896b0a4fbbbdc063bc4b0dbc25ce98e02b5050c24aeb7830ac02039b14
|
| 2 |
+
|
| 3 |
+
# Preserve the pinned vLLM/PyTorch/CUDA/CUTLASS/Triton stack.
|
| 4 |
+
COPY requirements.txt /opt/naive/requirements.txt
|
| 5 |
+
RUN python3 -m pip install --no-cache-dir --no-deps --target /opt/naive-python -r /opt/naive/requirements.txt \
|
| 6 |
+
&& python3 -m pip install --no-cache-dir --no-deps --target /opt/flashinfer-v070 flashinfer-python==0.7.0
|
| 7 |
+
COPY scripts/ /opt/naive/scripts/
|
| 8 |
+
COPY sitecustomize.py /opt/naive-python/sitecustomize.py
|
| 9 |
+
COPY pyproject.toml /opt/vllm-naive/pyproject.toml
|
| 10 |
+
COPY vllm_naive/ /opt/vllm-naive/vllm_naive/
|
| 11 |
+
RUN python3 -m pip install --no-deps --no-build-isolation /opt/vllm-naive
|
| 12 |
+
ENV PYTHONPATH=/opt/flashinfer-v070:/opt/naive-python:/opt/naive/scripts \
|
| 13 |
+
NAIVE_FLASHINFER_SOURCE_ONLY=1 \
|
| 14 |
+
NAIVE_EXPERT_BACKEND=fused \
|
| 15 |
+
FLASHINFER_WORKSPACE_BASE=/cache/flashinfer-v070 \
|
| 16 |
+
HF_MODULES_CACHE=/cache/hf-modules \
|
| 17 |
+
TORCH_EXTENSIONS_DIR=/cache/torch-extensions \
|
| 18 |
+
TRITON_CACHE_DIR=/cache/triton \
|
| 19 |
+
XDG_CACHE_HOME=/cache/xdg \
|
| 20 |
+
HF_HUB_OFFLINE=1 \
|
| 21 |
+
TRANSFORMERS_OFFLINE=1 \
|
| 22 |
+
OMP_NUM_THREADS=1 \
|
| 23 |
+
NCCL_P2P_DISABLE=1 \
|
| 24 |
+
VLLM_PLUGINS=naive_n05 \
|
| 25 |
+
VLLM_WORKER_MULTIPROC_METHOD=spawn \
|
| 26 |
+
VLLM_CACHE_ROOT=/cache/vllm \
|
| 27 |
+
VLLM_FLOAT32_MATMUL_PRECISION=highest
|
| 28 |
+
WORKDIR /opt/naive
|
| 29 |
+
ENTRYPOINT ["python3", "-m", "vllm.entrypoints.openai.api_server"]
|
runtime/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2026 Naive NVFP4 runtime contributors
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
runtime/LICENSE-APACHE-2.0.txt
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
Apache License
|
| 3 |
+
Version 2.0, January 2004
|
| 4 |
+
http://www.apache.org/licenses/
|
| 5 |
+
|
| 6 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
| 7 |
+
|
| 8 |
+
1. Definitions.
|
| 9 |
+
|
| 10 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
| 11 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
| 12 |
+
|
| 13 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
| 14 |
+
the copyright owner that is granting the License.
|
| 15 |
+
|
| 16 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
| 17 |
+
other entities that control, are controlled by, or are under common
|
| 18 |
+
control with that entity. For the purposes of this definition,
|
| 19 |
+
"control" means (i) the power, direct or indirect, to cause the
|
| 20 |
+
direction or management of such entity, whether by contract or
|
| 21 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
| 22 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
| 23 |
+
|
| 24 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
| 25 |
+
exercising permissions granted by this License.
|
| 26 |
+
|
| 27 |
+
"Source" form shall mean the preferred form for making modifications,
|
| 28 |
+
including but not limited to software source code, documentation
|
| 29 |
+
source, and configuration files.
|
| 30 |
+
|
| 31 |
+
"Object" form shall mean any form resulting from mechanical
|
| 32 |
+
transformation or translation of a Source form, including but
|
| 33 |
+
not limited to compiled object code, generated documentation,
|
| 34 |
+
and conversions to other media types.
|
| 35 |
+
|
| 36 |
+
"Work" shall mean the work of authorship, whether in Source or
|
| 37 |
+
Object form, made available under the License, as indicated by a
|
| 38 |
+
copyright notice that is included in or attached to the work
|
| 39 |
+
(an example is provided in the Appendix below).
|
| 40 |
+
|
| 41 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
| 42 |
+
form, that is based on (or derived from) the Work and for which the
|
| 43 |
+
editorial revisions, annotations, elaborations, or other modifications
|
| 44 |
+
represent, as a whole, an original work of authorship. For the purposes
|
| 45 |
+
of this License, Derivative Works shall not include works that remain
|
| 46 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
| 47 |
+
the Work and Derivative Works thereof.
|
| 48 |
+
|
| 49 |
+
"Contribution" shall mean any work of authorship, including
|
| 50 |
+
the original version of the Work and any modifications or additions
|
| 51 |
+
to that Work or Derivative Works thereof, that is intentionally
|
| 52 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
| 53 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
| 54 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
| 55 |
+
means any form of electronic, verbal, or written communication sent
|
| 56 |
+
to the Licensor or its representatives, including but not limited to
|
| 57 |
+
communication on electronic mailing lists, source code control systems,
|
| 58 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
| 59 |
+
Licensor for the purpose of discussing and improving the Work, but
|
| 60 |
+
excluding communication that is conspicuously marked or otherwise
|
| 61 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
| 62 |
+
|
| 63 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
| 64 |
+
on behalf of whom a Contribution has been received by Licensor and
|
| 65 |
+
subsequently incorporated within the Work.
|
| 66 |
+
|
| 67 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
| 68 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 69 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 70 |
+
copyright license to reproduce, prepare Derivative Works of,
|
| 71 |
+
publicly display, publicly perform, sublicense, and distribute the
|
| 72 |
+
Work and such Derivative Works in Source or Object form.
|
| 73 |
+
|
| 74 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
| 75 |
+
this License, each Contributor hereby grants to You a perpetual,
|
| 76 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
| 77 |
+
(except as stated in this section) patent license to make, have made,
|
| 78 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
| 79 |
+
where such license applies only to those patent claims licensable
|
| 80 |
+
by such Contributor that are necessarily infringed by their
|
| 81 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
| 82 |
+
with the Work to which such Contribution(s) was submitted. If You
|
| 83 |
+
institute patent litigation against any entity (including a
|
| 84 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
| 85 |
+
or a Contribution incorporated within the Work constitutes direct
|
| 86 |
+
or contributory patent infringement, then any patent licenses
|
| 87 |
+
granted to You under this License for that Work shall terminate
|
| 88 |
+
as of the date such litigation is filed.
|
| 89 |
+
|
| 90 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
| 91 |
+
Work or Derivative Works thereof in any medium, with or without
|
| 92 |
+
modifications, and in Source or Object form, provided that You
|
| 93 |
+
meet the following conditions:
|
| 94 |
+
|
| 95 |
+
(a) You must give any other recipients of the Work or
|
| 96 |
+
Derivative Works a copy of this License; and
|
| 97 |
+
|
| 98 |
+
(b) You must cause any modified files to carry prominent notices
|
| 99 |
+
stating that You changed the files; and
|
| 100 |
+
|
| 101 |
+
(c) You must retain, in the Source form of any Derivative Works
|
| 102 |
+
that You distribute, all copyright, patent, trademark, and
|
| 103 |
+
attribution notices from the Source form of the Work,
|
| 104 |
+
excluding those notices that do not pertain to any part of
|
| 105 |
+
the Derivative Works; and
|
| 106 |
+
|
| 107 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
| 108 |
+
distribution, then any Derivative Works that You distribute must
|
| 109 |
+
include a readable copy of the attribution notices contained
|
| 110 |
+
within such NOTICE file, excluding those notices that do not
|
| 111 |
+
pertain to any part of the Derivative Works, in at least one
|
| 112 |
+
of the following places: within a NOTICE text file distributed
|
| 113 |
+
as part of the Derivative Works; within the Source form or
|
| 114 |
+
documentation, if provided along with the Derivative Works; or,
|
| 115 |
+
within a display generated by the Derivative Works, if and
|
| 116 |
+
wherever such third-party notices normally appear. The contents
|
| 117 |
+
of the NOTICE file are for informational purposes only and
|
| 118 |
+
do not modify the License. You may add Your own attribution
|
| 119 |
+
notices within Derivative Works that You distribute, alongside
|
| 120 |
+
or as an addendum to the NOTICE text from the Work, provided
|
| 121 |
+
that such additional attribution notices cannot be construed
|
| 122 |
+
as modifying the License.
|
| 123 |
+
|
| 124 |
+
You may add Your own copyright statement to Your modifications and
|
| 125 |
+
may provide additional or different license terms and conditions
|
| 126 |
+
for use, reproduction, or distribution of Your modifications, or
|
| 127 |
+
for any such Derivative Works as a whole, provided Your use,
|
| 128 |
+
reproduction, and distribution of the Work otherwise complies with
|
| 129 |
+
the conditions stated in this License.
|
| 130 |
+
|
| 131 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
| 132 |
+
any Contribution intentionally submitted for inclusion in the Work
|
| 133 |
+
by You to the Licensor shall be under the terms and conditions of
|
| 134 |
+
this License, without any additional terms or conditions.
|
| 135 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
| 136 |
+
the terms of any separate license agreement you may have executed
|
| 137 |
+
with Licensor regarding such Contributions.
|
| 138 |
+
|
| 139 |
+
6. Trademarks. This License does not grant permission to use the trade
|
| 140 |
+
names, trademarks, service marks, or product names of the Licensor,
|
| 141 |
+
except as required for reasonable and customary use in describing the
|
| 142 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
| 143 |
+
|
| 144 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
| 145 |
+
agreed to in writing, Licensor provides the Work (and each
|
| 146 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
| 147 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
| 148 |
+
implied, including, without limitation, any warranties or conditions
|
| 149 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
| 150 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
| 151 |
+
appropriateness of using or redistributing the Work and assume any
|
| 152 |
+
risks associated with Your exercise of permissions under this License.
|
| 153 |
+
|
| 154 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
| 155 |
+
whether in tort (including negligence), contract, or otherwise,
|
| 156 |
+
unless required by applicable law (such as deliberate and grossly
|
| 157 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
| 158 |
+
liable to You for damages, including any direct, indirect, special,
|
| 159 |
+
incidental, or consequential damages of any character arising as a
|
| 160 |
+
result of this License or out of the use or inability to use the
|
| 161 |
+
Work (including but not limited to damages for loss of goodwill,
|
| 162 |
+
work stoppage, computer failure or malfunction, or any and all
|
| 163 |
+
other commercial damages or losses), even if such Contributor
|
| 164 |
+
has been advised of the possibility of such damages.
|
| 165 |
+
|
| 166 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
| 167 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
| 168 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
| 169 |
+
or other liability obligations and/or rights consistent with this
|
| 170 |
+
License. However, in accepting such obligations, You may act only
|
| 171 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
| 172 |
+
of any other Contributor, and only if You agree to indemnify,
|
| 173 |
+
defend, and hold each Contributor harmless for any liability
|
| 174 |
+
incurred by, or claims asserted against, such Contributor by reason
|
| 175 |
+
of your accepting any such warranty or additional liability.
|
| 176 |
+
|
| 177 |
+
END OF TERMS AND CONDITIONS
|
| 178 |
+
|
| 179 |
+
APPENDIX: How to apply the Apache License to your work.
|
| 180 |
+
|
| 181 |
+
To apply the Apache License to your work, attach the following
|
| 182 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
| 183 |
+
replaced with your own identifying information. (Don't include
|
| 184 |
+
the brackets!) The text should be enclosed in the appropriate
|
| 185 |
+
comment syntax for the file format. We also recommend that a
|
| 186 |
+
file or class name and description of purpose be included on the
|
| 187 |
+
same "printed page" as the copyright notice for easier
|
| 188 |
+
identification within third-party archives.
|
| 189 |
+
|
| 190 |
+
Copyright [yyyy] [name of copyright owner]
|
| 191 |
+
|
| 192 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
| 193 |
+
you may not use this file except in compliance with the License.
|
| 194 |
+
You may obtain a copy of the License at
|
| 195 |
+
|
| 196 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
| 197 |
+
|
| 198 |
+
Unless required by applicable law or agreed to in writing, software
|
| 199 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
| 200 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 201 |
+
See the License for the specific language governing permissions and
|
| 202 |
+
limitations under the License.
|
runtime/THIRD_PARTY_NOTICES.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Licensing and attribution
|
| 2 |
+
|
| 3 |
+
The quantized model is derived from Naive AI's `Naive-N0.5-Flash` checkpoint.
|
| 4 |
+
Its MIT license and copyright notice are preserved in the repository's root
|
| 5 |
+
`LICENSE` file. Naive AI describes the original model as a derivative of
|
| 6 |
+
Xiaomi MiMo-V2.5; see the linked upstream model card for that lineage.
|
| 7 |
+
|
| 8 |
+
The upstream `configuration_naive_n05_flash.py` and
|
| 9 |
+
`modeling_naive_n05_flash.py` retain their original Apache-2.0 copyright and
|
| 10 |
+
license headers. The Apache-2.0 license text is in `LICENSE-APACHE-2.0.txt`.
|
| 11 |
+
|
| 12 |
+
The additional runtime scripts and deployment files in `runtime/`, and the
|
| 13 |
+
root `compose.yml`, are provided under the MIT terms in `runtime/LICENSE`.
|
| 14 |
+
Dependencies downloaded during the Docker build retain their own licenses;
|
| 15 |
+
the dependency image and Python packages are not redistributed in this
|
| 16 |
+
repository.
|
runtime/pyproject.toml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[build-system]
|
| 2 |
+
requires = ["setuptools>=68"]
|
| 3 |
+
build-backend = "setuptools.build_meta"
|
| 4 |
+
|
| 5 |
+
[project]
|
| 6 |
+
name = "vllm-naive-n05"
|
| 7 |
+
version = "0.1.0"
|
| 8 |
+
requires-python = ">=3.12"
|
| 9 |
+
|
| 10 |
+
[project.entry-points."vllm.general_plugins"]
|
| 11 |
+
naive_n05 = "vllm_naive:register"
|
| 12 |
+
|
| 13 |
+
[tool.setuptools.packages.find]
|
| 14 |
+
include = ["vllm_naive*"]
|
runtime/requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Install into an isolated target over the pinned CUDA/PyTorch base image.
|
| 2 |
+
transformers==5.17.0
|
| 3 |
+
accelerate==1.15.0
|
| 4 |
+
tokenizers==0.23.2
|
| 5 |
+
huggingface-hub==1.33.0
|
| 6 |
+
safetensors==0.8.0
|
runtime/scripts/benchmark_stream.py
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Measure real vLLM streamed token delivery, with exact returned token IDs."""
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import time
|
| 5 |
+
import urllib.request
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
PROMPTS = [
|
| 9 |
+
'Explain how a hash table works in Python, including collisions, resizing, and time complexity. Write a detailed tutorial of at least 800 words.',
|
| 10 |
+
'Write a complete Python implementation of an LRU cache with type annotations, a detailed explanation, and examples. Include at least 800 words of explanation after the code.',
|
| 11 |
+
]
|
| 12 |
+
for repetitions in (90, 210, 410):
|
| 13 |
+
PROMPTS.append(
|
| 14 |
+
'This is background information for a technical documentation exercise. The system stores records and processes requests.\n' * repetitions
|
| 15 |
+
+ 'Now write a detailed tutorial of at least 800 words explaining database indexes and their tradeoffs.')
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def request(base_url, model, prompt, maximum):
|
| 19 |
+
body = {'model':model, 'messages':[{'role':'user','content':prompt}],
|
| 20 |
+
'temperature':0, 'max_tokens':maximum, 'chat_template_kwargs':{'enable_thinking':False},
|
| 21 |
+
'stream':True, 'stream_options':{'include_usage':True}, 'return_token_ids':True}
|
| 22 |
+
req = urllib.request.Request(base_url.rstrip('/')+'/chat/completions',
|
| 23 |
+
data=json.dumps(body).encode(), headers={'Content-Type':'application/json'})
|
| 24 |
+
start = time.perf_counter()
|
| 25 |
+
events, content, reasoning = [], [], []
|
| 26 |
+
usage = None
|
| 27 |
+
with urllib.request.urlopen(req, timeout=1800) as response:
|
| 28 |
+
for line in response:
|
| 29 |
+
if not line.startswith(b'data: '):
|
| 30 |
+
continue
|
| 31 |
+
payload = line[6:].strip()
|
| 32 |
+
if payload == b'[DONE]':
|
| 33 |
+
break
|
| 34 |
+
chunk = json.loads(payload)
|
| 35 |
+
if 'error' in chunk:
|
| 36 |
+
raise RuntimeError(chunk['error'])
|
| 37 |
+
if chunk.get('usage') is not None:
|
| 38 |
+
usage = chunk['usage']
|
| 39 |
+
for choice in chunk.get('choices',[]):
|
| 40 |
+
tokens = choice.get('token_ids') or []
|
| 41 |
+
if tokens:
|
| 42 |
+
events.append({'elapsed_seconds':time.perf_counter()-start,'token_ids':tokens})
|
| 43 |
+
delta = choice.get('delta',{})
|
| 44 |
+
content.append(delta.get('content') or '')
|
| 45 |
+
reasoning.append(delta.get('reasoning') or delta.get('reasoning_content') or '')
|
| 46 |
+
wall = time.perf_counter()-start
|
| 47 |
+
count = sum(len(event['token_ids']) for event in events)
|
| 48 |
+
assert usage and count == usage['completion_tokens'], (count,usage)
|
| 49 |
+
assert len(events) >= 2, 'At least two token-bearing SSE events are required.'
|
| 50 |
+
first_count = len(events[0]['token_ids'])
|
| 51 |
+
seconds = events[-1]['elapsed_seconds']-events[0]['elapsed_seconds']
|
| 52 |
+
return {'request':body,'usage':usage,'content':''.join(content),'reasoning':''.join(reasoning),
|
| 53 |
+
'wall_seconds':wall,'time_to_first_token_seconds':events[0]['elapsed_seconds'],
|
| 54 |
+
'decode_tokens':count-first_count,'decode_seconds':seconds,
|
| 55 |
+
'decode_tokens_per_second':(count-first_count)/seconds,
|
| 56 |
+
'end_to_end_tokens_per_second':count/wall,'first_event_token_count':first_count,
|
| 57 |
+
'token_events':events}
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def main():
|
| 61 |
+
parser = argparse.ArgumentParser()
|
| 62 |
+
parser.add_argument('--base-url',default='http://127.0.0.1:8000/v1')
|
| 63 |
+
parser.add_argument('--model',default='Naive-N0.5-Flash-NVFP4')
|
| 64 |
+
parser.add_argument('--tokens',type=int,default=256)
|
| 65 |
+
parser.add_argument('--cases',type=int,default=5)
|
| 66 |
+
parser.add_argument('--output',type=Path,required=True)
|
| 67 |
+
args = parser.parse_args()
|
| 68 |
+
request(args.base_url,args.model,'Explain why the sky is blue in several sentences.',32)
|
| 69 |
+
results=[]
|
| 70 |
+
for prompt in PROMPTS[:args.cases]:
|
| 71 |
+
result=request(args.base_url,args.model,prompt,args.tokens)
|
| 72 |
+
assert result['usage']['completion_tokens'] >= min(128,args.tokens)
|
| 73 |
+
results.append(result)
|
| 74 |
+
print(json.dumps({key:result[key] for key in ('usage','time_to_first_token_seconds',
|
| 75 |
+
'decode_tokens_per_second','end_to_end_tokens_per_second')}),flush=True)
|
| 76 |
+
report={'engine':'vLLM','measurement':'Client wall time between token-bearing SSE events, using exact token IDs; first event excluded from decode rate',
|
| 77 |
+
'single_active_request':True,'cases':results,'complete':len(results)==args.cases,
|
| 78 |
+
'target_met':len(results)==args.cases and all(r['decode_tokens_per_second']>=50 for r in results)}
|
| 79 |
+
args.output.parent.mkdir(parents=True,exist_ok=True)
|
| 80 |
+
args.output.write_text(json.dumps(report,indent=2)+'\n')
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
if __name__ == '__main__':
|
| 84 |
+
main()
|
runtime/scripts/decode_kernels.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Small fused decode kernels, preserving the reference BF16 rounding points."""
|
| 2 |
+
import torch
|
| 3 |
+
import triton
|
| 4 |
+
import triton.language as tl
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
@triton.jit
|
| 8 |
+
def _rmsnorm(x, weight, output, H: tl.constexpr, EPS: tl.constexpr, BLOCK: tl.constexpr):
|
| 9 |
+
row = tl.program_id(0)
|
| 10 |
+
cols = tl.arange(0, BLOCK)
|
| 11 |
+
data = tl.load(x + row * H + cols, cols < H, other=0).to(tl.float32)
|
| 12 |
+
scale = tl.rsqrt(tl.sum(data * data, 0) / H + EPS)
|
| 13 |
+
# LlamaRMSNorm rounds normalized activations before applying its weight.
|
| 14 |
+
normalized = (data * scale).to(tl.bfloat16).to(tl.float32)
|
| 15 |
+
w = tl.load(weight + cols, cols < H, other=0).to(tl.float32)
|
| 16 |
+
tl.store(output + row * H + cols, normalized * w, cols < H)
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def rmsnorm(states, weight, eps):
|
| 20 |
+
assert states.is_contiguous() and states.dtype == torch.bfloat16
|
| 21 |
+
width = states.shape[-1]
|
| 22 |
+
result = torch.empty_like(states)
|
| 23 |
+
_rmsnorm[(states.numel() // width,)](states, weight, result, width, eps,
|
| 24 |
+
triton.next_power_of_2(width), num_warps=4, enable_fp_fusion=False)
|
| 25 |
+
return result
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
@triton.jit
|
| 29 |
+
def _rotary_pair(Q, K, COS, SIN, POS, OQ, OK, HQ: tl.constexpr, D: tl.constexpr,
|
| 30 |
+
R: tl.constexpr, BLOCK: tl.constexpr):
|
| 31 |
+
head = tl.program_id(0)
|
| 32 |
+
dims = tl.arange(0, BLOCK)
|
| 33 |
+
position = tl.load(POS)
|
| 34 |
+
source = tl.where(head < HQ, Q + head * D, K + (head - HQ) * D)
|
| 35 |
+
destination = tl.where(head < HQ, OQ + head * D, OK + (head - HQ) * D)
|
| 36 |
+
values = tl.load(source + dims, dims < D, other=0).to(tl.float32)
|
| 37 |
+
partner = (dims + R // 2) % R
|
| 38 |
+
other = tl.load(source + partner, dims < R, other=0).to(tl.float32)
|
| 39 |
+
other = tl.where(dims < R // 2, -other, other)
|
| 40 |
+
cos = tl.load(COS + position * R + dims, dims < R, other=1).to(tl.float32)
|
| 41 |
+
sin = tl.load(SIN + position * R + dims, dims < R, other=0).to(tl.float32)
|
| 42 |
+
rotated = (values * cos).to(tl.bfloat16).to(tl.float32) + (other * sin).to(tl.bfloat16).to(tl.float32)
|
| 43 |
+
tl.store(destination + dims, tl.where(dims < R, rotated, values), dims < D)
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def rotary_pair(query, key, position, cos, sin):
|
| 47 |
+
dimension = query.shape[-1]
|
| 48 |
+
assert query.shape[0] == query.shape[2] == 1 and query.stride(1) == dimension
|
| 49 |
+
oq = torch.empty_like(query, memory_format=torch.contiguous_format)
|
| 50 |
+
if key is None:
|
| 51 |
+
key, ok, key_heads = query, oq, 0
|
| 52 |
+
else:
|
| 53 |
+
assert key.shape[-1] == dimension and key.stride(1) == dimension
|
| 54 |
+
ok, key_heads = torch.empty_like(key, memory_format=torch.contiguous_format), key.shape[1]
|
| 55 |
+
_rotary_pair[(query.shape[1] + key_heads,)](query, key, cos, sin, position, oq, ok,
|
| 56 |
+
query.shape[1], dimension, cos.shape[-1], triton.next_power_of_2(dimension),
|
| 57 |
+
num_warps=4, enable_fp_fusion=False)
|
| 58 |
+
return oq, ok if key_heads else None
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
@triton.jit
|
| 62 |
+
def _small_attention(Q, K, V, MASK, SINK, OUT,
|
| 63 |
+
L: tl.constexpr, D: tl.constexpr, DV: tl.constexpr, GROUP: tl.constexpr,
|
| 64 |
+
KS: tl.constexpr, VS: tl.constexpr, SCALE: tl.constexpr, VALUE_SCALE: tl.constexpr,
|
| 65 |
+
HAS_SINK: tl.constexpr, BN: tl.constexpr, BD: tl.constexpr, BV: tl.constexpr):
|
| 66 |
+
head = tl.program_id(0)
|
| 67 |
+
kv = head // GROUP
|
| 68 |
+
rows, dims = tl.arange(0, BN), tl.arange(0, BD)
|
| 69 |
+
q = tl.load(Q + head * D + dims, dims < D, other=0).to(tl.float32)
|
| 70 |
+
k = tl.load(K + kv * KS + rows[:, None] * D + dims[None, :],
|
| 71 |
+
(rows[:, None] < L) & (dims[None, :] < D), other=0).to(tl.float32)
|
| 72 |
+
logits = (tl.sum(k * q[None, :], 1).to(tl.bfloat16).to(tl.float32) * SCALE).to(tl.bfloat16).to(tl.float32)
|
| 73 |
+
valid = tl.load(MASK + rows, rows < L, other=False)
|
| 74 |
+
logits = tl.where(valid & (rows < L), logits, -float('inf'))
|
| 75 |
+
maximum = tl.max(logits, 0)
|
| 76 |
+
sink = -float('inf')
|
| 77 |
+
if HAS_SINK:
|
| 78 |
+
sink = tl.load(SINK + head).to(tl.float32)
|
| 79 |
+
maximum = tl.maximum(maximum, sink)
|
| 80 |
+
exps = tl.exp(logits - maximum)
|
| 81 |
+
denominator = tl.sum(exps, 0)
|
| 82 |
+
if HAS_SINK:
|
| 83 |
+
denominator += tl.exp(sink - maximum)
|
| 84 |
+
probabilities = (exps / denominator).to(tl.bfloat16).to(tl.float32)
|
| 85 |
+
vd = tl.arange(0, BV)
|
| 86 |
+
values = tl.load(V + kv * VS + rows[:, None] * DV + vd[None, :],
|
| 87 |
+
(rows[:, None] < L) & (vd[None, :] < DV), other=0).to(tl.float32)
|
| 88 |
+
values = (values * VALUE_SCALE).to(tl.bfloat16).to(tl.float32)
|
| 89 |
+
result = tl.sum(probabilities[:, None] * values, 0)
|
| 90 |
+
tl.store(OUT + head * DV + vd, result, vd < DV)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
@triton.jit
|
| 94 |
+
def _attention_logits(Q, K, MASK, LOGITS, L: tl.constexpr, D: tl.constexpr,
|
| 95 |
+
GROUP: tl.constexpr, KS: tl.constexpr, SCALE: tl.constexpr,
|
| 96 |
+
BN: tl.constexpr, BD: tl.constexpr):
|
| 97 |
+
head, block = tl.program_id(0), tl.program_id(1)
|
| 98 |
+
rows, dims = block * BN + tl.arange(0, BN), tl.arange(0, BD)
|
| 99 |
+
q = tl.load(Q + head * D + dims, dims < D, other=0).to(tl.float32)
|
| 100 |
+
k = tl.load(K + (head // GROUP) * KS + rows[:, None] * D + dims[None, :],
|
| 101 |
+
(rows[:, None] < L) & (dims[None, :] < D), other=0).to(tl.float32)
|
| 102 |
+
logits = (tl.sum(k * q[None, :], 1).to(tl.bfloat16).to(tl.float32) * SCALE).to(tl.bfloat16)
|
| 103 |
+
valid = tl.load(MASK + rows, rows < L, other=False)
|
| 104 |
+
tl.store(LOGITS + head * L + rows, tl.where(valid, logits, -float('inf')), rows < L)
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
@triton.jit
|
| 108 |
+
def _attention_probabilities(LOGITS, SINK, PROBS, L: tl.constexpr, HAS_SINK: tl.constexpr, BN: tl.constexpr):
|
| 109 |
+
head = tl.program_id(0)
|
| 110 |
+
rows = tl.arange(0, BN)
|
| 111 |
+
logits = tl.load(LOGITS + head * L + rows, rows < L, other=-float('inf')).to(tl.float32)
|
| 112 |
+
maximum = tl.max(logits, 0)
|
| 113 |
+
sink = -float('inf')
|
| 114 |
+
if HAS_SINK:
|
| 115 |
+
sink = tl.load(SINK + head).to(tl.float32)
|
| 116 |
+
maximum = tl.maximum(maximum, sink)
|
| 117 |
+
exps = tl.exp(logits - maximum)
|
| 118 |
+
denominator = tl.sum(exps, 0)
|
| 119 |
+
if HAS_SINK:
|
| 120 |
+
denominator += tl.exp(sink - maximum)
|
| 121 |
+
tl.store(PROBS + head * L + rows, exps / denominator, rows < L)
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
@triton.jit
|
| 125 |
+
def _attention_values(PROBS, V, OUT, L: tl.constexpr, DV: tl.constexpr,
|
| 126 |
+
GROUP: tl.constexpr, VS: tl.constexpr, VALUE_SCALE: tl.constexpr,
|
| 127 |
+
BN: tl.constexpr, BV: tl.constexpr):
|
| 128 |
+
head = tl.program_id(0)
|
| 129 |
+
dims = tl.arange(0, BV)
|
| 130 |
+
result = tl.full((BV,), 0, tl.float32)
|
| 131 |
+
for block in range(tl.cdiv(L, BN)):
|
| 132 |
+
rows = block * BN + tl.arange(0, BN)
|
| 133 |
+
probabilities = tl.load(PROBS + head * L + rows, rows < L, other=0).to(tl.float32)
|
| 134 |
+
values = tl.load(V + (head // GROUP) * VS + rows[:, None] * DV + dims[None, :],
|
| 135 |
+
(rows[:, None] < L) & (dims[None, :] < DV), other=0).to(tl.float32)
|
| 136 |
+
values = (values * VALUE_SCALE).to(tl.bfloat16).to(tl.float32)
|
| 137 |
+
result += tl.sum(probabilities[:, None] * values, 0)
|
| 138 |
+
tl.store(OUT + head * DV + dims, result, dims < DV)
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def decode_attention(query, keys, values, allowed, sink, value_scale):
|
| 142 |
+
heads, dimension = query.shape[1], query.shape[-1]
|
| 143 |
+
length, value_dimension = keys.shape[-2], values.shape[-1]
|
| 144 |
+
assert query.shape[0] == query.shape[2] == 1
|
| 145 |
+
assert keys.stride(-1) == values.stride(-1) == 1
|
| 146 |
+
assert keys.stride(-2) == dimension and values.stride(-2) == value_dimension
|
| 147 |
+
result = torch.empty((1, heads, 1, value_dimension), device=query.device, dtype=query.dtype)
|
| 148 |
+
sink_pointer = sink if sink is not None else result
|
| 149 |
+
group = heads // keys.shape[1]
|
| 150 |
+
scale = dimension ** -.5
|
| 151 |
+
value_scale = 1. if value_scale is None else value_scale
|
| 152 |
+
if length <= 128:
|
| 153 |
+
_small_attention[(heads,)](query, keys, values, allowed, sink_pointer, result,
|
| 154 |
+
length, dimension, value_dimension, group, keys.stride(1), values.stride(1),
|
| 155 |
+
scale, value_scale, sink is not None, triton.next_power_of_2(length),
|
| 156 |
+
triton.next_power_of_2(dimension), triton.next_power_of_2(value_dimension),
|
| 157 |
+
num_warps=8, enable_fp_fusion=False)
|
| 158 |
+
else:
|
| 159 |
+
logits = torch.empty((heads, length), dtype=torch.bfloat16, device=query.device)
|
| 160 |
+
probabilities = torch.empty_like(logits)
|
| 161 |
+
_attention_logits[(heads, triton.cdiv(length, 64))](query, keys, allowed, logits,
|
| 162 |
+
length, dimension, group, keys.stride(1), scale, 64, triton.next_power_of_2(dimension),
|
| 163 |
+
num_warps=4, enable_fp_fusion=False)
|
| 164 |
+
_attention_probabilities[(heads,)](logits, sink_pointer, probabilities, length,
|
| 165 |
+
sink is not None, triton.next_power_of_2(length), num_warps=4)
|
| 166 |
+
_attention_values[(heads,)](probabilities, values, result, length, value_dimension,
|
| 167 |
+
group, values.stride(1), value_scale, 64, triton.next_power_of_2(value_dimension),
|
| 168 |
+
num_warps=4, enable_fp_fusion=False)
|
| 169 |
+
return result
|
runtime/scripts/fused_experts.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Fused SM120 NVFP4 experts; original checkpoint weights and calibrated scales."""
|
| 2 |
+
import torch
|
| 3 |
+
from torch import nn
|
| 4 |
+
from flashinfer import nvfp4_block_scale_interleave
|
| 5 |
+
from flashinfer.cute_dsl.utils import convert_sf_to_mma_layout
|
| 6 |
+
from flashinfer.fused_moe import B12xMoEWrapper
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class FusedNVFP4Experts(nn.Module):
|
| 10 |
+
def __init__(self, reader, prefix, num_experts, hidden, intermediate, device, top_k=8, max_tokens=256):
|
| 11 |
+
super().__init__()
|
| 12 |
+
self.num_experts, self.hidden, self.intermediate = num_experts, hidden, intermediate
|
| 13 |
+
w1 = torch.empty((num_experts, 2 * intermediate, hidden // 2), dtype=torch.uint8, device=device)
|
| 14 |
+
w2 = torch.empty((num_experts, hidden, intermediate // 2), dtype=torch.uint8, device=device)
|
| 15 |
+
sf1 = torch.empty((num_experts, 2 * intermediate, hidden // 16), dtype=torch.uint8, device=device)
|
| 16 |
+
sf2 = torch.empty((num_experts, hidden, intermediate // 16), dtype=torch.uint8, device=device)
|
| 17 |
+
globals1, globals2, inputs1, inputs2 = [], [], [], []
|
| 18 |
+
for expert in range(num_experts):
|
| 19 |
+
name = f'{prefix}{expert}.'
|
| 20 |
+
values = {p + '.' + k: reader.get_tensor(name + p + '.' + k)
|
| 21 |
+
for p in ('gate_proj', 'up_proj', 'down_proj')
|
| 22 |
+
for k in ('weight', 'weight_scale', 'weight_scale_2', 'input_scale')}
|
| 23 |
+
for kind in ('weight_scale_2', 'input_scale'):
|
| 24 |
+
assert torch.equal(values['gate_proj.' + kind], values['up_proj.' + kind])
|
| 25 |
+
# b12x uses [up, gate]; the reference linear uses [gate, up].
|
| 26 |
+
w1[expert, :intermediate].copy_(values['up_proj.weight'])
|
| 27 |
+
w1[expert, intermediate:].copy_(values['gate_proj.weight'])
|
| 28 |
+
w2[expert].copy_(values['down_proj.weight'])
|
| 29 |
+
logical = torch.cat([values['up_proj.weight_scale'], values['gate_proj.weight_scale']])
|
| 30 |
+
sf1[expert].copy_(nvfp4_block_scale_interleave(logical.view(torch.uint8)).reshape_as(sf1[expert]))
|
| 31 |
+
sf2[expert].copy_(nvfp4_block_scale_interleave(values['down_proj.weight_scale'].view(torch.uint8)).reshape_as(sf2[expert]))
|
| 32 |
+
globals1.append(values['gate_proj.weight_scale_2'].reshape(()))
|
| 33 |
+
globals2.append(values['down_proj.weight_scale_2'].reshape(()))
|
| 34 |
+
inputs1.append(values['gate_proj.input_scale'].reshape(()))
|
| 35 |
+
inputs2.append(values['down_proj.input_scale'].reshape(()))
|
| 36 |
+
for key, value in dict(w1=w1, w2=w2,
|
| 37 |
+
sf1=convert_sf_to_mma_layout(sf1.view(torch.float8_e4m3fn), m=2*intermediate, k=hidden, num_groups=num_experts),
|
| 38 |
+
sf2=convert_sf_to_mma_layout(sf2.view(torch.float8_e4m3fn), m=hidden, k=intermediate, num_groups=num_experts),
|
| 39 |
+
alpha1=torch.stack(globals1).float(),
|
| 40 |
+
alpha2=torch.stack(globals2).float() * torch.stack(inputs2).float(),
|
| 41 |
+
input1=torch.stack(inputs1).float(), input2=torch.stack(inputs2).float()).items():
|
| 42 |
+
self.register_buffer(key, value)
|
| 43 |
+
self.wrapper = B12xMoEWrapper(num_experts, top_k, hidden, intermediate,
|
| 44 |
+
use_cuda_graph=True, max_num_tokens=max_tokens, device=str(device), quant_mode='nvfp4')
|
| 45 |
+
|
| 46 |
+
def forward(self, hidden_states, top_k_index, top_k_weights):
|
| 47 |
+
with torch.cuda.device(hidden_states.device):
|
| 48 |
+
return self.wrapper.run(hidden_states, self.w1, self.sf1, self.w2, self.sf2,
|
| 49 |
+
top_k_index, top_k_weights, w1_alpha=self.alpha1, w2_alpha=self.alpha2,
|
| 50 |
+
fc2_input_scale=self.input2, input_global_scale=self.input1)
|
runtime/scripts/nvfp4_runtime.py
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Reference local runtime: upstream Naive attention and native Blackwell expert GEMMs.
|
| 2 |
+
|
| 3 |
+
Loads ModelOpt's standard packed checkpoint without changing the source architecture.
|
| 4 |
+
Expert dispatch is eager PyTorch; the matrix multiplications execute as NVFP4 W4A4.
|
| 5 |
+
"""
|
| 6 |
+
import os
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
ROOT = Path(__file__).resolve().parents[1]
|
| 10 |
+
os.environ.setdefault("HF_MODULES_CACHE", str(ROOT / "artifacts/hf-modules"))
|
| 11 |
+
|
| 12 |
+
import torch
|
| 13 |
+
import torch.nn as nn
|
| 14 |
+
import torch.nn.functional as F
|
| 15 |
+
from accelerate import init_empty_weights, dispatch_model
|
| 16 |
+
from accelerate.utils import set_module_tensor_to_device
|
| 17 |
+
from flashinfer import nvfp4_quantize, nvfp4_block_scale_interleave, mm_fp4, SfLayout
|
| 18 |
+
from safetensors import safe_open
|
| 19 |
+
from transformers import AutoConfig, AutoModelForCausalLM
|
| 20 |
+
from safe_device_transfer import install as install_safe_transfers
|
| 21 |
+
|
| 22 |
+
class NVFP4Linear(nn.Module):
|
| 23 |
+
def __init__(self, weight, weight_scale, weight_scale_2, input_scale, backend="cutlass"):
|
| 24 |
+
super().__init__()
|
| 25 |
+
assert weight.dtype == torch.uint8
|
| 26 |
+
assert weight_scale.dtype == torch.float8_e4m3fn
|
| 27 |
+
assert weight_scale.shape == (weight.shape[0], weight.shape[1] // 8)
|
| 28 |
+
assert torch.isfinite(weight_scale.float()).all()
|
| 29 |
+
assert weight_scale_2.numel() == input_scale.numel() == 1
|
| 30 |
+
assert weight_scale_2.item() > 0 and input_scale.item() > 0
|
| 31 |
+
self.register_buffer("weight", weight.contiguous())
|
| 32 |
+
self.register_buffer("scales", nvfp4_block_scale_interleave(weight_scale.contiguous().view(torch.uint8)))
|
| 33 |
+
self.register_buffer("input_scale_inv", input_scale.float().reciprocal().reshape(1))
|
| 34 |
+
self.register_buffer("alpha", (weight_scale_2.float() * input_scale.float()).reshape(1))
|
| 35 |
+
self.backend = backend
|
| 36 |
+
|
| 37 |
+
def forward(self, states):
|
| 38 |
+
shape = states.shape
|
| 39 |
+
states = states.reshape(-1, shape[-1]).contiguous()
|
| 40 |
+
# FlashInfer's quantizer calls .cuda() internally, so its current device
|
| 41 |
+
# must follow the layer's placement in a multi-GPU model.
|
| 42 |
+
with torch.cuda.device(states.device):
|
| 43 |
+
packed, scales = nvfp4_quantize(states, self.input_scale_inv,
|
| 44 |
+
sfLayout=SfLayout.layout_128x4, do_shuffle=False)
|
| 45 |
+
output = mm_fp4(packed, self.weight.T, scales, self.scales,
|
| 46 |
+
self.alpha, out_dtype=states.dtype, backend=self.backend)
|
| 47 |
+
return output.reshape(*shape[:-1], self.weight.shape[0])
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class NVFP4Expert(nn.Module):
|
| 51 |
+
def __init__(self, tensors, backend):
|
| 52 |
+
super().__init__()
|
| 53 |
+
for suffix in ("weight_scale_2", "input_scale"):
|
| 54 |
+
if not torch.equal(tensors[f"gate_proj.{suffix}"], tensors[f"up_proj.{suffix}"]):
|
| 55 |
+
raise ValueError(f"Exported gate/up {suffix} must match before fusion")
|
| 56 |
+
self.gate_up = NVFP4Linear(
|
| 57 |
+
torch.cat([tensors["gate_proj.weight"], tensors["up_proj.weight"]]),
|
| 58 |
+
torch.cat([tensors["gate_proj.weight_scale"], tensors["up_proj.weight_scale"]]),
|
| 59 |
+
tensors["gate_proj.weight_scale_2"], tensors["gate_proj.input_scale"], backend)
|
| 60 |
+
self.down = NVFP4Linear(tensors["down_proj.weight"], tensors["down_proj.weight_scale"],
|
| 61 |
+
tensors["down_proj.weight_scale_2"], tensors["down_proj.input_scale"], backend)
|
| 62 |
+
|
| 63 |
+
def forward(self, states):
|
| 64 |
+
gate, up = self.gate_up(states).chunk(2, dim=-1)
|
| 65 |
+
return self.down(F.silu(gate) * up)
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
class NVFP4Experts(nn.Module):
|
| 69 |
+
def __init__(self, experts):
|
| 70 |
+
super().__init__()
|
| 71 |
+
self.experts = nn.ModuleList(experts)
|
| 72 |
+
|
| 73 |
+
def forward(self, hidden_states, top_k_index, top_k_weights):
|
| 74 |
+
output = torch.zeros_like(hidden_states)
|
| 75 |
+
for expert_id in top_k_index.unique().tolist():
|
| 76 |
+
tokens, slots = torch.where(top_k_index == expert_id)
|
| 77 |
+
current = self.experts[expert_id](hidden_states[tokens])
|
| 78 |
+
weighted = current * top_k_weights[tokens, slots, None].to(current.dtype)
|
| 79 |
+
output.index_add_(0, tokens, weighted)
|
| 80 |
+
return output
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def load_model(checkpoint, devices=None, backend="cutlass"):
|
| 84 |
+
install_safe_transfers()
|
| 85 |
+
os.environ.setdefault("HF_MODULES_CACHE", str(ROOT / "artifacts/hf-modules"))
|
| 86 |
+
checkpoint = Path(checkpoint).resolve()
|
| 87 |
+
devices = list(range(torch.cuda.device_count())) if devices is None else devices
|
| 88 |
+
if not devices:
|
| 89 |
+
raise ValueError("At least one Blackwell GPU is required")
|
| 90 |
+
for device in devices:
|
| 91 |
+
assert torch.cuda.get_device_capability(device)[0] >= 10
|
| 92 |
+
config = AutoConfig.from_pretrained(checkpoint, trust_remote_code=True)
|
| 93 |
+
if config.model_type != "naive_n05_flash":
|
| 94 |
+
raise ValueError(f"Unexpected model type: {config.model_type}")
|
| 95 |
+
if hasattr(config, "quantization_config"):
|
| 96 |
+
del config.quantization_config
|
| 97 |
+
config.use_cache = True
|
| 98 |
+
with init_empty_weights():
|
| 99 |
+
model = AutoModelForCausalLM.from_config(config, trust_remote_code=True, dtype=torch.bfloat16)
|
| 100 |
+
device_map = {"model.embed_tokens": devices[0], "model.norm": devices[-1], "lm_head": devices[-1]}
|
| 101 |
+
for i in range(config.num_hidden_layers):
|
| 102 |
+
device_map[f"model.layers.{i}"] = devices[min(i * len(devices) // config.num_hidden_layers, len(devices) - 1)]
|
| 103 |
+
import json
|
| 104 |
+
index = json.loads((checkpoint / "model.safetensors.index.json").read_text())["weight_map"]
|
| 105 |
+
loaded = set()
|
| 106 |
+
# Each ModelOpt layer export is a self-contained shard. Expert tensors are
|
| 107 |
+
# read by exact name so a missing scale fails instead of silently initializing.
|
| 108 |
+
for layer_id, layer in enumerate(model.model.layers):
|
| 109 |
+
prefix = f"model.layers.{layer_id}."
|
| 110 |
+
gpu = device_map[prefix[:-1]]
|
| 111 |
+
names = [name for name in index if name.startswith(prefix)]
|
| 112 |
+
shards = {index[name] for name in names}
|
| 113 |
+
if len(shards) != 1:
|
| 114 |
+
raise ValueError("This loader requires one self-contained shard per decoder layer")
|
| 115 |
+
with torch.cuda.device(gpu), safe_open(checkpoint / next(iter(shards)), framework="pt", device=gpu) as reader:
|
| 116 |
+
if config.moe_layer_freq[layer_id]:
|
| 117 |
+
if os.environ.get('NAIVE_EXPERT_BACKEND', 'reference') == 'fused':
|
| 118 |
+
from fused_experts import FusedNVFP4Experts
|
| 119 |
+
layer.mlp.experts = FusedNVFP4Experts(reader, f'{prefix}mlp.experts.',
|
| 120 |
+
config.n_routed_experts, config.hidden_size, config.moe_intermediate_size,
|
| 121 |
+
torch.device(f'cuda:{gpu}'), top_k=config.num_experts_per_tok,
|
| 122 |
+
max_tokens=int(os.environ.get('PREFILL_CHUNK', '256')))
|
| 123 |
+
loaded.update(name for name in names if name.startswith(f'{prefix}mlp.experts.'))
|
| 124 |
+
else:
|
| 125 |
+
experts = []
|
| 126 |
+
for expert_id in range(config.n_routed_experts):
|
| 127 |
+
ep = f"{prefix}mlp.experts.{expert_id}."
|
| 128 |
+
tensors = {projection + "." + kind: reader.get_tensor(ep + projection + "." + kind)
|
| 129 |
+
for projection in ("gate_proj", "up_proj", "down_proj")
|
| 130 |
+
for kind in ("weight", "weight_scale", "weight_scale_2", "input_scale")}
|
| 131 |
+
experts.append(NVFP4Expert(tensors, backend))
|
| 132 |
+
loaded.update(ep + name for name in tensors)
|
| 133 |
+
layer.mlp.experts = NVFP4Experts(experts)
|
| 134 |
+
for name in names:
|
| 135 |
+
if name in loaded:
|
| 136 |
+
continue
|
| 137 |
+
tensor = reader.get_tensor(name)
|
| 138 |
+
set_module_tensor_to_device(model, name, gpu, value=tensor, dtype=tensor.dtype)
|
| 139 |
+
loaded.add(name)
|
| 140 |
+
print(f"Loaded layer {layer_id + 1}/{config.num_hidden_layers} on cuda:{gpu}", flush=True)
|
| 141 |
+
remaining = set(index) - loaded
|
| 142 |
+
for name in sorted(remaining):
|
| 143 |
+
module_name = name.rsplit(".", 1)[0]
|
| 144 |
+
if module_name not in device_map:
|
| 145 |
+
raise ValueError(f"Unrecognized tensor outside decoder layers: {name}")
|
| 146 |
+
gpu = device_map[module_name]
|
| 147 |
+
with safe_open(checkpoint / index[name], framework="pt", device=gpu) as reader:
|
| 148 |
+
tensor = reader.get_tensor(name)
|
| 149 |
+
set_module_tensor_to_device(model, name, gpu, value=tensor, dtype=tensor.dtype)
|
| 150 |
+
loaded.add(name)
|
| 151 |
+
assert loaded == set(index)
|
| 152 |
+
assert not any(p.is_meta for p in model.parameters())
|
| 153 |
+
model = dispatch_model(model, device_map=device_map, force_hooks=True)
|
| 154 |
+
return model.eval().requires_grad_(False)
|
runtime/scripts/preflight.py
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Check the tested four-GPU environment and shard headers without loading weights."""
|
| 2 |
+
import importlib.metadata
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
import struct
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
import torch
|
| 9 |
+
|
| 10 |
+
from flashinfer.fused_moe import B12xMoEWrapper
|
| 11 |
+
from transformers import AutoConfig, AutoTokenizer
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def main():
|
| 15 |
+
versions = {name: importlib.metadata.version(name) for name in (
|
| 16 |
+
'vllm', 'torch', 'transformers', 'accelerate', 'tokenizers', 'huggingface-hub',
|
| 17 |
+
'safetensors', 'flashinfer-python', 'nvidia-cutlass-dsl', 'triton')}
|
| 18 |
+
expected = {'vllm': '0.28.0', 'torch': '2.13.0+cu130', 'transformers': '5.17.0', 'accelerate': '1.15.0',
|
| 19 |
+
'tokenizers': '0.23.2', 'huggingface-hub': '1.33.0', 'safetensors': '0.8.0',
|
| 20 |
+
'flashinfer-python': '0.7.0', 'nvidia-cutlass-dsl': '4.6.2', 'triton': '3.7.1'}
|
| 21 |
+
assert versions == expected, {'expected': expected, 'actual': versions}
|
| 22 |
+
assert torch.cuda.device_count() == 4, 'This deployment recipe requires four visible GPUs.'
|
| 23 |
+
gpus = []
|
| 24 |
+
for index in range(4):
|
| 25 |
+
props = torch.cuda.get_device_properties(index)
|
| 26 |
+
assert (props.major, props.minor) == (12, 0), 'The fused B12x recipe targets SM120 Blackwell.'
|
| 27 |
+
assert props.total_memory >= 90 * 1024**3, 'The tested configuration uses four 96 GB GPUs.'
|
| 28 |
+
gpus.append({'index': index, 'name': props.name, 'memory_bytes': props.total_memory})
|
| 29 |
+
cache = Path('/cache')
|
| 30 |
+
cache.mkdir(parents=True, exist_ok=True)
|
| 31 |
+
probe = cache / '.write-check'
|
| 32 |
+
probe.write_text('ok\n')
|
| 33 |
+
probe.unlink()
|
| 34 |
+
checkpoint = Path(os.environ['MODEL_PATH'])
|
| 35 |
+
config = AutoConfig.from_pretrained(checkpoint, trust_remote_code=True)
|
| 36 |
+
assert config.model_type == 'naive_n05_flash'
|
| 37 |
+
tokenizer = AutoTokenizer.from_pretrained(checkpoint, trust_remote_code=True)
|
| 38 |
+
assert tokenizer.encode('Hello')
|
| 39 |
+
weight_map = json.loads((checkpoint / 'model.safetensors.index.json').read_text())['weight_map']
|
| 40 |
+
shards = sorted(set(weight_map.values()))
|
| 41 |
+
assert len(shards) == 49
|
| 42 |
+
discovered = {}
|
| 43 |
+
for name in shards:
|
| 44 |
+
shard = checkpoint / name
|
| 45 |
+
with shard.open('rb') as stream:
|
| 46 |
+
header_size = struct.unpack('<Q', stream.read(8))[0]
|
| 47 |
+
assert header_size < 100_000_000
|
| 48 |
+
header = json.loads(stream.read(header_size))
|
| 49 |
+
payload_end = 0
|
| 50 |
+
for key, metadata in header.items():
|
| 51 |
+
if key == '__metadata__':
|
| 52 |
+
continue
|
| 53 |
+
assert key not in discovered
|
| 54 |
+
discovered[key] = name
|
| 55 |
+
payload_end = max(payload_end, metadata['data_offsets'][1])
|
| 56 |
+
assert shard.stat().st_size == 8 + header_size + payload_end, name
|
| 57 |
+
assert discovered == weight_map, 'Shard headers and weight index differ.'
|
| 58 |
+
print(json.dumps({'passed': True, 'versions': versions, 'gpus': gpus,
|
| 59 |
+
'shards': len(shards), 'tensors': len(discovered)}, indent=2))
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
if __name__ == '__main__':
|
| 63 |
+
main()
|
runtime/scripts/safe_device_transfer.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Stage Accelerate's cross-GPU copies through host RAM on this workstation.
|
| 2 |
+
|
| 3 |
+
Direct CUDA peer copies report success but fail equality checks here. The existing
|
| 4 |
+
model-manager profiles also disable NCCL P2P. This adapter changes no driver or
|
| 5 |
+
global machine settings; it affects only this Python process.
|
| 6 |
+
"""
|
| 7 |
+
import torch
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def install():
|
| 11 |
+
import accelerate.hooks
|
| 12 |
+
import accelerate.utils
|
| 13 |
+
import accelerate.utils.operations as operations
|
| 14 |
+
if getattr(operations.send_to_device, "_host_staged", False):
|
| 15 |
+
return
|
| 16 |
+
original = operations.send_to_device
|
| 17 |
+
|
| 18 |
+
def send_to_device(tensor, device, non_blocking=False, skip_keys=None):
|
| 19 |
+
if isinstance(tensor, torch.Tensor) and tensor.is_cuda:
|
| 20 |
+
destination = torch.device(f"cuda:{device}" if isinstance(device, int) else device)
|
| 21 |
+
if destination.type == "cuda":
|
| 22 |
+
index = torch.cuda.current_device() if destination.index is None else destination.index
|
| 23 |
+
if tensor.device.index != index:
|
| 24 |
+
return tensor.to("cpu", non_blocking=False).to(destination, non_blocking=False)
|
| 25 |
+
return original(tensor, device, non_blocking=non_blocking, skip_keys=skip_keys)
|
| 26 |
+
|
| 27 |
+
send_to_device._host_staged = True
|
| 28 |
+
operations.send_to_device = send_to_device
|
| 29 |
+
accelerate.hooks.send_to_device = send_to_device
|
| 30 |
+
accelerate.utils.send_to_device = send_to_device
|
runtime/scripts/validate_api.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Record actual full-model answers, tool calls, longer context and throughput."""
|
| 2 |
+
import json
|
| 3 |
+
import os
|
| 4 |
+
import re
|
| 5 |
+
import subprocess
|
| 6 |
+
import time
|
| 7 |
+
import urllib.request
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
ROOT = Path(__file__).resolve().parents[2]
|
| 11 |
+
BASE = "http://127.0.0.1:8000"
|
| 12 |
+
MODEL = "Naive-N0.5-Flash-NVFP4"
|
| 13 |
+
REPORT_PATH = Path(os.environ.get('NAIVE_VALIDATION_FILE', 'native-vllm-api-validation.json'))
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def complete(prompt, **extra):
|
| 17 |
+
body = {"model": MODEL, "messages": [{"role": "user", "content": prompt}],
|
| 18 |
+
"temperature": 0, "max_tokens": 128,
|
| 19 |
+
"chat_template_kwargs": {"enable_thinking": False}, **extra}
|
| 20 |
+
request = urllib.request.Request(BASE + "/v1/chat/completions",
|
| 21 |
+
data=json.dumps(body).encode(), headers={"Content-Type": "application/json"})
|
| 22 |
+
print(f'Request: {prompt[-110:]}', flush=True)
|
| 23 |
+
start = time.monotonic()
|
| 24 |
+
with urllib.request.urlopen(request, timeout=1200) as response:
|
| 25 |
+
result = json.load(response)
|
| 26 |
+
elapsed = time.monotonic() - start
|
| 27 |
+
result["elapsed_seconds"] = elapsed
|
| 28 |
+
result["completion_tokens_per_second_including_prefill"] = result["usage"]["completion_tokens"] / elapsed
|
| 29 |
+
print(f'Completed in {elapsed:.1f}s: {result["usage"]}; {result["choices"][0]["message"]}', flush=True)
|
| 30 |
+
return result
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def main():
|
| 34 |
+
results = {}
|
| 35 |
+
try:
|
| 36 |
+
with urllib.request.urlopen(BASE + "/health") as response:
|
| 37 |
+
assert response.status == 200
|
| 38 |
+
with urllib.request.urlopen(BASE + "/v1/models") as response:
|
| 39 |
+
assert MODEL in {entry["id"] for entry in json.load(response)["data"]}
|
| 40 |
+
results["arithmetic"] = complete("What is 2 + 2? Reply with only the number.", max_tokens=32)
|
| 41 |
+
assert re.search(r"\b4\b", results["arithmetic"]["choices"][0]["message"].get("content") or "")
|
| 42 |
+
results["geography"] = complete("What is the capital of France? Reply with only its name.", max_tokens=32)
|
| 43 |
+
assert "paris" in (results["geography"]["choices"][0]["message"].get("content") or "").lower()
|
| 44 |
+
results["coding"] = complete("Write a Python function named add that returns the sum of two arguments. Return only the code.", max_tokens=128)
|
| 45 |
+
assert "def add" in (results["coding"]["choices"][0]["message"].get("content") or "")
|
| 46 |
+
tools = [{"type": "function", "function": {"name": "get_weather", "description": "Get weather for a city",
|
| 47 |
+
"parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}}}]
|
| 48 |
+
results["tools"] = complete("Call the get_weather tool for Warsaw. Do not answer from memory.", tools=tools, max_tokens=192)
|
| 49 |
+
calls = results["tools"]["choices"][0]["message"].get("tool_calls", [])
|
| 50 |
+
assert calls and calls[0]["function"]["name"] == "get_weather"
|
| 51 |
+
assert "warsaw" in calls[0]["function"]["arguments"].lower()
|
| 52 |
+
results["reasoning"] = complete("Calculate 6 times 7. Think briefly, then give the answer.",
|
| 53 |
+
chat_template_kwargs={"enable_thinking": True}, reasoning_effort="low", max_tokens=256)
|
| 54 |
+
reasoning_message = results["reasoning"]["choices"][0]["message"]
|
| 55 |
+
assert reasoning_message.get("reasoning")
|
| 56 |
+
assert re.search(r"\b42\b", reasoning_message.get("content") or "")
|
| 57 |
+
filler = "The following paragraph is background material about testing a language model. It contains no instructions.\n"
|
| 58 |
+
results["longer_context"] = complete(filler * 220 + "\nFinal question: what is 2 + 2? Answer only the number.", max_tokens=32)
|
| 59 |
+
assert results["longer_context"]["usage"]["prompt_tokens"] > 2048
|
| 60 |
+
assert re.search(r"\b4\b", results["longer_context"]["choices"][0]["message"].get("content") or "")
|
| 61 |
+
results["gpu_memory"] = subprocess.check_output(["nvidia-smi", "--query-gpu=index,memory.used,memory.total", "--format=csv"], text=True)
|
| 62 |
+
report = {"passed": True, "engine": "vLLM 0.28.0", "model": MODEL, "checks": results,
|
| 63 |
+
"scope": "Basic generation, coding, tool use and sparse-context smoke checks; not an accuracy benchmark"}
|
| 64 |
+
except Exception as error:
|
| 65 |
+
report = {"passed": False, "model": MODEL, "error": repr(error), "checks": results}
|
| 66 |
+
REPORT_PATH.write_text(json.dumps(report, indent=2) + "\n")
|
| 67 |
+
raise
|
| 68 |
+
REPORT_PATH.write_text(json.dumps(report, indent=2) + "\n")
|
| 69 |
+
print("FULL_MODEL_API_VALIDATION_PASSED", flush=True)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
if __name__ == "__main__":
|
| 73 |
+
main()
|
runtime/sitecustomize.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Isolate FlashInfer source kernels before vLLM worker imports execute."""
|
| 2 |
+
import os
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
if os.environ.get('NAIVE_FLASHINFER_SOURCE_ONLY') == '1':
|
| 6 |
+
sys.modules['flashinfer_jit_cache'] = None
|
| 7 |
+
sys.modules['flashinfer_cubin'] = None
|
runtime/vllm_naive/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Native model registration for vLLM's V1 engine."""
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
def register():
|
| 5 |
+
import sys
|
| 6 |
+
# FlashInfer 0.7 kernels must not use the base image's 0.6 prebuilt binaries.
|
| 7 |
+
sys.modules['flashinfer_jit_cache'] = None
|
| 8 |
+
sys.modules['flashinfer_cubin'] = None
|
| 9 |
+
from vllm import ModelRegistry
|
| 10 |
+
ModelRegistry.register_model('NaiveN05FlashForCausalLM',
|
| 11 |
+
'vllm_naive.model:NaiveN05FlashForCausalLM')
|
runtime/vllm_naive/attention.py
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Naive GQA sparse attention using vLLM-managed paged K/V/indexer storage.
|
| 2 |
+
|
| 3 |
+
Prefill and multiple active requests use eager operations; single-token decode
|
| 4 |
+
supports vLLM CUDA graphs. Both retain upstream indexer FP8 rounding and stable
|
| 5 |
+
sparse-selection ties.
|
| 6 |
+
"""
|
| 7 |
+
from dataclasses import dataclass
|
| 8 |
+
|
| 9 |
+
import torch
|
| 10 |
+
from torch import nn
|
| 11 |
+
from vllm.distributed import tensor_model_parallel_all_reduce
|
| 12 |
+
from vllm.forward_context import get_forward_context
|
| 13 |
+
from vllm.model_executor.layers.attention_layer_base import AttentionLayerBase
|
| 14 |
+
from vllm.v1.attention.backend import AttentionBackend, AttentionMetadataBuilder, AttentionCGSupport
|
| 15 |
+
from vllm.v1.kv_cache_interface import FullAttentionSpec
|
| 16 |
+
from decode_kernels import decode_attention, rotary_pair
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
@dataclass
|
| 20 |
+
class NaiveMetadata:
|
| 21 |
+
starts: list[int]
|
| 22 |
+
lengths: list[int]
|
| 23 |
+
block_table: torch.Tensor
|
| 24 |
+
slot_mapping: torch.Tensor
|
| 25 |
+
num_actual_tokens: int
|
| 26 |
+
single_decode: bool
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class NaiveMetadataBuilder(AttentionMetadataBuilder):
|
| 30 |
+
_cudagraph_support = AttentionCGSupport.UNIFORM_SINGLE_TOKEN_DECODE
|
| 31 |
+
|
| 32 |
+
def __init__(self, kv_cache_spec, layer_names, vllm_config, device):
|
| 33 |
+
super().__init__(kv_cache_spec, layer_names, vllm_config, device)
|
| 34 |
+
|
| 35 |
+
def build(self, common_prefix_len, common_attn_metadata, fast_build=False):
|
| 36 |
+
c = common_attn_metadata
|
| 37 |
+
single_decode = c.max_query_len == 1 and c.num_actual_tokens == 1
|
| 38 |
+
lengths = [] if single_decode else c.seq_lens.cpu().tolist()
|
| 39 |
+
return NaiveMetadata(c.query_start_loc_cpu.tolist(), lengths,
|
| 40 |
+
c.block_table_tensor, c.slot_mapping, c.num_actual_tokens, single_decode)
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
class NaiveBackend(AttentionBackend):
|
| 44 |
+
@staticmethod
|
| 45 |
+
def get_name():
|
| 46 |
+
return 'NAIVE_GQA_DSA'
|
| 47 |
+
|
| 48 |
+
@staticmethod
|
| 49 |
+
def get_impl_cls():
|
| 50 |
+
return NaivePagedAttention
|
| 51 |
+
|
| 52 |
+
@staticmethod
|
| 53 |
+
def get_builder_cls():
|
| 54 |
+
return NaiveMetadataBuilder
|
| 55 |
+
|
| 56 |
+
@staticmethod
|
| 57 |
+
def get_kv_cache_shape(num_blocks, block_size, num_kv_heads, head_size, cache_dtype_str='auto'):
|
| 58 |
+
return (num_blocks, 2, block_size, num_kv_heads, head_size)
|
| 59 |
+
|
| 60 |
+
@staticmethod
|
| 61 |
+
def get_kv_cache_stride_order(include_num_layers_dimension=False):
|
| 62 |
+
return tuple(range(6 if include_num_layers_dimension else 5))
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def round_fp8(states):
|
| 66 |
+
values = states.float()
|
| 67 |
+
scale = values.abs().amax(-1, keepdim=True).clamp_min(1e-4) / 448.
|
| 68 |
+
return (values / scale).clamp(-448, 448).to(torch.float8_e4m3fn).float() * scale
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
class NaivePagedAttention(nn.Module, AttentionLayerBase):
|
| 72 |
+
supports_dcp = False
|
| 73 |
+
|
| 74 |
+
def __init__(self, source, name, vllm_config, tp_size, tp_rank):
|
| 75 |
+
super().__init__()
|
| 76 |
+
self.config = source.config
|
| 77 |
+
self.name = name
|
| 78 |
+
self.tp_size = tp_size
|
| 79 |
+
self.is_swa = source.is_swa
|
| 80 |
+
self.heads = source.heads // tp_size
|
| 81 |
+
self.kv_heads = source.kv_heads // tp_size
|
| 82 |
+
assert source.heads % tp_size == source.kv_heads % tp_size == 0
|
| 83 |
+
self.head_dim, self.v_dim = source.head_dim, source.v_dim
|
| 84 |
+
self.num_heads = self.heads
|
| 85 |
+
self.cache_heads = max(self.config.num_key_value_heads, self.config.swa_num_key_value_heads) // tp_size
|
| 86 |
+
self.cache_width = max(self.config.head_dim, self.config.swa_head_dim) + self.config.index_head_dim
|
| 87 |
+
self.block_size = vllm_config.cache_config.block_size
|
| 88 |
+
self.max_context = vllm_config.model_config.max_model_len
|
| 89 |
+
for key in ('q_proj', 'k_proj', 'v_proj', 'o_proj', 'rotary_emb', 'indexer'):
|
| 90 |
+
setattr(self, key, getattr(source, key))
|
| 91 |
+
self.attention_sink_bias = source.attention_sink_bias
|
| 92 |
+
for key in ('q_proj', 'k_proj', 'v_proj'):
|
| 93 |
+
module = getattr(self, key)
|
| 94 |
+
module.out_features //= tp_size
|
| 95 |
+
module.weight = nn.Parameter(torch.empty(module.out_features, module.in_features, device='meta', dtype=torch.bfloat16))
|
| 96 |
+
self.o_proj.in_features //= tp_size
|
| 97 |
+
self.o_proj.weight = nn.Parameter(torch.empty(self.o_proj.out_features, self.o_proj.in_features, device='meta', dtype=torch.bfloat16))
|
| 98 |
+
if self.attention_sink_bias is not None:
|
| 99 |
+
self.attention_sink_bias = nn.Parameter(torch.empty(self.heads, device='meta', dtype=torch.bfloat16), requires_grad=False)
|
| 100 |
+
self.kv_cache = torch.empty(0)
|
| 101 |
+
context = vllm_config.compilation_config.static_forward_context
|
| 102 |
+
assert name not in context
|
| 103 |
+
context[name] = self
|
| 104 |
+
|
| 105 |
+
def get_attn_backend(self):
|
| 106 |
+
return NaiveBackend
|
| 107 |
+
|
| 108 |
+
def get_kv_cache_spec(self, vllm_config):
|
| 109 |
+
self.block_size = vllm_config.cache_config.block_size
|
| 110 |
+
# Indexer values after FP8 rounding carry FP32 scales. Storing all cache
|
| 111 |
+
# elements as FP32 preserves them exactly; K/V are cast back to BF16.
|
| 112 |
+
return FullAttentionSpec(block_size=self.block_size, num_kv_heads=self.cache_heads,
|
| 113 |
+
head_size=self.cache_width, dtype=torch.float32)
|
| 114 |
+
|
| 115 |
+
def initialize_decode(self):
|
| 116 |
+
"""Share packed projection storage and precompute fixed rotary tables."""
|
| 117 |
+
projections = (self.q_proj, self.k_proj, self.v_proj)
|
| 118 |
+
assert all(projection.bias is None for projection in projections)
|
| 119 |
+
sizes = [projection.weight.shape[0] for projection in projections]
|
| 120 |
+
packed = torch.cat([projection.weight for projection in projections])
|
| 121 |
+
self.register_buffer('qkv_weight', packed, persistent=False)
|
| 122 |
+
# Retain the original projection interfaces for prefill without keeping
|
| 123 |
+
# a second copy of the projection weights on the GPU.
|
| 124 |
+
for projection, weight in zip(projections, packed.split(sizes)):
|
| 125 |
+
projection.weight = nn.Parameter(weight, requires_grad=False)
|
| 126 |
+
self.qkv_sizes = sizes
|
| 127 |
+
positions = torch.arange(self.max_context, device=packed.device).unsqueeze(0)
|
| 128 |
+
cos, sin = self.rotary_emb(packed.new_empty((1, 1, 1)), positions)
|
| 129 |
+
self.register_buffer('decode_cos', cos.contiguous(), persistent=False)
|
| 130 |
+
self.register_buffer('decode_sin', sin.contiguous(), persistent=False)
|
| 131 |
+
|
| 132 |
+
def forward(self, states, positions):
|
| 133 |
+
from transformers.models.gpt_neox.modeling_gpt_neox import apply_rotary_pos_emb
|
| 134 |
+
length = states.shape[0]
|
| 135 |
+
if length == 1:
|
| 136 |
+
query, key, value = torch.nn.functional.linear(states, self.qkv_weight).split(self.qkv_sizes, dim=-1)
|
| 137 |
+
else:
|
| 138 |
+
query, key, value = self.q_proj(states), self.k_proj(states), self.v_proj(states)
|
| 139 |
+
query = query.view(1, length, self.heads, self.head_dim).transpose(1, 2)
|
| 140 |
+
key = key.view(1, length, self.kv_heads, self.head_dim).transpose(1, 2)
|
| 141 |
+
value = value.view(length, self.kv_heads, self.v_dim)
|
| 142 |
+
if length == 1:
|
| 143 |
+
query, key = rotary_pair(query, key, positions, self.decode_cos, self.decode_sin)
|
| 144 |
+
else:
|
| 145 |
+
embeddings = self.rotary_emb(states.unsqueeze(0), positions.unsqueeze(0))
|
| 146 |
+
query, key = apply_rotary_pos_emb(query, key, *embeddings)
|
| 147 |
+
index_query = index_key = index_weights = None
|
| 148 |
+
if self.indexer is not None:
|
| 149 |
+
c = self.config
|
| 150 |
+
index_query = self.indexer.wq(states).view(1, length, c.index_n_heads, c.index_head_dim).transpose(1, 2)
|
| 151 |
+
index_key = self.indexer.k_norm(self.indexer.wk(states)).view(1, 1, length, c.index_head_dim)
|
| 152 |
+
if length == 1:
|
| 153 |
+
index_query, _ = rotary_pair(index_query, None, positions, self.decode_cos, self.decode_sin)
|
| 154 |
+
index_key, _ = rotary_pair(index_key, None, positions, self.decode_cos, self.decode_sin)
|
| 155 |
+
else:
|
| 156 |
+
index_query, index_key = apply_rotary_pos_emb(index_query, index_key, *embeddings)
|
| 157 |
+
if c.indexer_activation_dtype == 'fp8_e4m3':
|
| 158 |
+
index_query, index_key = round_fp8(index_query), round_fp8(index_key)
|
| 159 |
+
index_weights = self.indexer.weights_proj(states) * c.index_n_heads**-.5
|
| 160 |
+
metadata = get_forward_context().attn_metadata
|
| 161 |
+
metadata = metadata.get(self.name) if metadata else None
|
| 162 |
+
if metadata is None:
|
| 163 |
+
# vLLM's memory profiling pass has no cache metadata.
|
| 164 |
+
return self.o_proj(torch.zeros(length, self.heads*self.v_dim, dtype=states.dtype, device=states.device))
|
| 165 |
+
n = metadata.num_actual_tokens
|
| 166 |
+
# vLLM uses negative slots for graph-capture dummy tokens. Page zero is
|
| 167 |
+
# its null block; real scheduled tokens always have allocated slots.
|
| 168 |
+
slots = metadata.slot_mapping[:n].long().clamp_min(0)
|
| 169 |
+
blocks, offsets = slots // self.block_size, slots % self.block_size
|
| 170 |
+
self.kv_cache[blocks, 0, offsets, :self.kv_heads, :self.head_dim] = key[0].transpose(0, 1)[:n].float()
|
| 171 |
+
self.kv_cache[blocks, 1, offsets, :self.kv_heads, :self.v_dim] = value[:n].float()
|
| 172 |
+
if index_key is not None:
|
| 173 |
+
self.kv_cache[blocks, 0, offsets, 0, -self.config.index_head_dim:] = index_key[0, 0, :n].float()
|
| 174 |
+
if metadata.single_decode:
|
| 175 |
+
return self.decode(query, positions, index_query, index_weights, metadata)
|
| 176 |
+
output = torch.zeros(length, self.heads*self.v_dim, device=states.device, dtype=states.dtype)
|
| 177 |
+
for request, (start, end) in enumerate(zip(metadata.starts, metadata.starts[1:])):
|
| 178 |
+
if start == end:
|
| 179 |
+
continue
|
| 180 |
+
total = metadata.lengths[request]
|
| 181 |
+
first = max(0, total - (end-start) - self.config.sliding_window + 1) if self.is_swa else 0
|
| 182 |
+
key_positions = torch.arange(first, total, device=states.device)
|
| 183 |
+
page = metadata.block_table[request, key_positions // self.block_size].long()
|
| 184 |
+
offset = key_positions % self.block_size
|
| 185 |
+
keys = self.kv_cache[page, 0, offset, :self.kv_heads, :self.head_dim].to(states.dtype).transpose(0, 1)
|
| 186 |
+
values = self.kv_cache[page, 1, offset, :self.kv_heads, :self.v_dim].to(states.dtype).transpose(0, 1)
|
| 187 |
+
allowed = positions[start:end, None] >= key_positions[None]
|
| 188 |
+
if self.is_swa:
|
| 189 |
+
allowed = allowed & ((positions[start:end, None] - key_positions[None]) < self.config.sliding_window)
|
| 190 |
+
else:
|
| 191 |
+
cached_index = self.kv_cache[page, 0, offset, 0, -self.config.index_head_dim:]
|
| 192 |
+
scores = (index_query[0, :, start:end].float() @ cached_index.T).relu()
|
| 193 |
+
scores = (scores * index_weights[start:end].T[:, :, None].float()).sum(0)
|
| 194 |
+
scores = scores.masked_fill(~allowed, -torch.inf)
|
| 195 |
+
selected = scores.argsort(dim=-1, descending=True, stable=True)[:, :self.config.index_top_k]
|
| 196 |
+
allowed = allowed & torch.zeros_like(scores, dtype=torch.bool).scatter(-1, selected, True)
|
| 197 |
+
keys = keys.repeat_interleave(self.heads//self.kv_heads, dim=0)
|
| 198 |
+
values = values.repeat_interleave(self.heads//self.kv_heads, dim=0)
|
| 199 |
+
if self.config.attention_value_scale is not None:
|
| 200 |
+
values = values * self.config.attention_value_scale
|
| 201 |
+
logits = (query[0, :, start:end] @ keys.transpose(-1, -2)) * self.head_dim**-.5
|
| 202 |
+
logits = logits.masked_fill(~allowed[None], -torch.inf)
|
| 203 |
+
if self.attention_sink_bias is not None:
|
| 204 |
+
sinks = self.attention_sink_bias[:, None, None].expand(-1, end-start, 1)
|
| 205 |
+
logits = torch.cat((logits, sinks), -1)
|
| 206 |
+
probabilities = logits.float().softmax(-1).nan_to_num(0)[..., :len(key_positions)].to(values.dtype)
|
| 207 |
+
output[start:end] = (probabilities @ values).transpose(0, 1).reshape(end-start, -1)
|
| 208 |
+
output = self.o_proj(output)
|
| 209 |
+
return tensor_model_parallel_all_reduce(output) if self.tp_size > 1 else output
|
| 210 |
+
|
| 211 |
+
def decode(self, query, positions, index_query, index_weights, metadata):
|
| 212 |
+
"""Fixed-shape single-token path for vLLM's full decode CUDA graphs."""
|
| 213 |
+
if self.is_swa:
|
| 214 |
+
key_positions = positions[0] - self.config.sliding_window + 1 + torch.arange(
|
| 215 |
+
self.config.sliding_window, device=query.device)
|
| 216 |
+
valid = key_positions >= 0
|
| 217 |
+
key_positions = key_positions.clamp_min(0)
|
| 218 |
+
else:
|
| 219 |
+
key_positions = torch.arange(self.max_context, device=query.device)
|
| 220 |
+
valid = key_positions <= positions[0]
|
| 221 |
+
pages = metadata.block_table[0, key_positions // self.block_size].long()
|
| 222 |
+
pages = torch.where(valid, pages, 0)
|
| 223 |
+
cached_index = self.kv_cache[pages, 0, key_positions % self.block_size,
|
| 224 |
+
0, -self.config.index_head_dim:]
|
| 225 |
+
scores = (index_query[0].float() @ cached_index.T).relu()
|
| 226 |
+
scores = (scores * index_weights.T[:, :, None].float()).sum(0)
|
| 227 |
+
scores = scores.masked_fill(~valid[None], -torch.inf)
|
| 228 |
+
selected = scores.argsort(dim=-1, descending=True, stable=True)[0, :self.config.index_top_k]
|
| 229 |
+
key_positions = selected.sort().values
|
| 230 |
+
valid = key_positions <= positions[0]
|
| 231 |
+
pages = metadata.block_table[0, key_positions // self.block_size].long()
|
| 232 |
+
pages = torch.where(valid, pages, 0)
|
| 233 |
+
offsets = key_positions % self.block_size
|
| 234 |
+
keys = self.kv_cache[pages, 0, offsets, :self.kv_heads, :self.head_dim].to(query.dtype).transpose(0, 1).contiguous()
|
| 235 |
+
values = self.kv_cache[pages, 1, offsets, :self.kv_heads, :self.v_dim].to(query.dtype).transpose(0, 1).contiguous()
|
| 236 |
+
# Unallocated/padding entries may contain arbitrary bits in the cache.
|
| 237 |
+
keys = keys.masked_fill(~valid[None, :, None], 0)
|
| 238 |
+
values = values.masked_fill(~valid[None, :, None], 0)
|
| 239 |
+
output = decode_attention(query, keys[None], values[None], valid,
|
| 240 |
+
self.attention_sink_bias, self.config.attention_value_scale)
|
| 241 |
+
output = self.o_proj(output.transpose(1, 2).reshape(1, -1))
|
| 242 |
+
return tensor_model_parallel_all_reduce(output) if self.tp_size > 1 else output
|
runtime/vllm_naive/model.py
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Naive-N0.5-Flash NVFP4 model executed by the native vLLM V1 model runner."""
|
| 2 |
+
import copy
|
| 3 |
+
import json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
|
| 6 |
+
import torch
|
| 7 |
+
from torch import nn
|
| 8 |
+
from accelerate import init_empty_weights
|
| 9 |
+
from accelerate.utils import set_module_tensor_to_device
|
| 10 |
+
from safetensors import safe_open
|
| 11 |
+
from transformers import AutoModelForCausalLM
|
| 12 |
+
from vllm.distributed import get_tensor_model_parallel_rank, get_tensor_model_parallel_world_size, tensor_model_parallel_all_reduce
|
| 13 |
+
from vllm_naive.attention import NaivePagedAttention
|
| 14 |
+
|
| 15 |
+
from fused_experts import FusedNVFP4Experts
|
| 16 |
+
from nvfp4_runtime import NVFP4Expert, NVFP4Experts
|
| 17 |
+
from decode_kernels import rmsnorm
|
| 18 |
+
from flashinfer.fused_moe.cute_dsl.blackwell_sm12x import moe_dispatch
|
| 19 |
+
|
| 20 |
+
# FlashInfer 0.7's direct-micro path returned all-zero output for this model's
|
| 21 |
+
# calibrated NVFP4 scales at TP4 (intermediate=512, one token). Keep the regular
|
| 22 |
+
# MMA micro/static/dynamic paths. Covered by validate_expert_sharding.py.
|
| 23 |
+
moe_dispatch._DIRECT_MICRO_MAX_N = 0
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
class ShardedReader:
|
| 27 |
+
def __init__(self, reader, rank, size, device):
|
| 28 |
+
self.reader, self.rank, self.size, self.device = reader, rank, size, device
|
| 29 |
+
|
| 30 |
+
def get_tensor(self, name):
|
| 31 |
+
tensor = self.reader.get_tensor(name)
|
| 32 |
+
if name.endswith(('.weight', '.weight_scale')):
|
| 33 |
+
dim = 1 if '.down_proj.' in name else 0
|
| 34 |
+
assert tensor.shape[dim] % self.size == 0
|
| 35 |
+
tensor = tensor.chunk(self.size, dim=dim)[self.rank].contiguous()
|
| 36 |
+
return tensor.to(self.device)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
class ReduceExperts(nn.Module):
|
| 40 |
+
def __init__(self, experts, tp_size):
|
| 41 |
+
super().__init__()
|
| 42 |
+
self.experts, self.tp_size = experts, tp_size
|
| 43 |
+
|
| 44 |
+
def forward(self, hidden_states, top_k_index, top_k_weights):
|
| 45 |
+
result = self.experts(hidden_states, top_k_index, top_k_weights)
|
| 46 |
+
return tensor_model_parallel_all_reduce(result) if self.tp_size > 1 else result
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
class StaticReferenceExperts(NVFP4Experts):
|
| 50 |
+
"""Small-fixture reference kernels with no data-dependent Python dispatch."""
|
| 51 |
+
|
| 52 |
+
def forward(self, hidden_states, top_k_index, top_k_weights):
|
| 53 |
+
output = torch.zeros_like(hidden_states)
|
| 54 |
+
for expert_id, expert in enumerate(self.experts):
|
| 55 |
+
weight = (top_k_weights * (top_k_index == expert_id)).sum(-1).to(hidden_states.dtype)
|
| 56 |
+
output = output + expert(hidden_states) * weight[:, None]
|
| 57 |
+
return output
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
class ShardedDense(nn.Module):
|
| 61 |
+
def __init__(self, source, tp_size):
|
| 62 |
+
super().__init__()
|
| 63 |
+
self.tp_size = tp_size
|
| 64 |
+
self.act_fn = source.act_fn
|
| 65 |
+
for name in ('gate_proj', 'up_proj', 'down_proj'):
|
| 66 |
+
module = getattr(source, name)
|
| 67 |
+
if name == 'down_proj':
|
| 68 |
+
module.in_features //= tp_size
|
| 69 |
+
else:
|
| 70 |
+
module.out_features //= tp_size
|
| 71 |
+
module.weight = nn.Parameter(torch.empty(module.out_features, module.in_features,
|
| 72 |
+
dtype=torch.bfloat16, device='meta'))
|
| 73 |
+
setattr(self, name, module)
|
| 74 |
+
|
| 75 |
+
def forward(self, states):
|
| 76 |
+
result = self.down_proj(self.act_fn(self.gate_proj(states)) * self.up_proj(states))
|
| 77 |
+
return tensor_model_parallel_all_reduce(result) if self.tp_size > 1 else result
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
class NaiveN05FlashForCausalLM(nn.Module):
|
| 81 |
+
packed_modules_mapping = {}
|
| 82 |
+
|
| 83 |
+
def __init__(self, *, vllm_config, prefix=''):
|
| 84 |
+
super().__init__()
|
| 85 |
+
self.vllm_config = vllm_config
|
| 86 |
+
assert vllm_config.parallel_config.pipeline_parallel_size == 1
|
| 87 |
+
self.tp_size = get_tensor_model_parallel_world_size()
|
| 88 |
+
self.tp_rank = get_tensor_model_parallel_rank()
|
| 89 |
+
self.config = copy.deepcopy(vllm_config.model_config.hf_config)
|
| 90 |
+
if hasattr(self.config, 'quantization_config'):
|
| 91 |
+
del self.config.quantization_config
|
| 92 |
+
with init_empty_weights():
|
| 93 |
+
original = AutoModelForCausalLM.from_config(self.config, trust_remote_code=True, dtype=torch.bfloat16)
|
| 94 |
+
self.model, self.lm_head = original.model, original.lm_head
|
| 95 |
+
for i, layer in enumerate(self.model.layers):
|
| 96 |
+
layer.self_attn = NaivePagedAttention(layer.self_attn, f'model.layers.{i}.self_attn',
|
| 97 |
+
vllm_config, self.tp_size, self.tp_rank)
|
| 98 |
+
if not self.config.moe_layer_freq[i]:
|
| 99 |
+
layer.mlp = ShardedDense(layer.mlp, self.tp_size)
|
| 100 |
+
|
| 101 |
+
def embed_input_ids(self, input_ids):
|
| 102 |
+
return self.model.embed_tokens(input_ids)
|
| 103 |
+
|
| 104 |
+
def forward(self, input_ids, positions, intermediate_tensors=None, inputs_embeds=None):
|
| 105 |
+
states = self.embed_input_ids(input_ids) if inputs_embeds is None else inputs_embeds
|
| 106 |
+
for layer in self.model.layers:
|
| 107 |
+
norm = layer.input_layernorm
|
| 108 |
+
states = states + layer.self_attn(rmsnorm(states, norm.weight, norm.variance_epsilon), positions)
|
| 109 |
+
norm = layer.post_attention_layernorm
|
| 110 |
+
states = states + layer.mlp(rmsnorm(states, norm.weight, norm.variance_epsilon))
|
| 111 |
+
return rmsnorm(states, self.model.norm.weight, self.model.norm.variance_epsilon)
|
| 112 |
+
|
| 113 |
+
def compute_logits(self, hidden_states):
|
| 114 |
+
# Vocabulary and embedding/head are replicated across TP ranks.
|
| 115 |
+
return self.lm_head(hidden_states)
|
| 116 |
+
|
| 117 |
+
def load_weights(self, weights):
|
| 118 |
+
# Layer shards allow streaming only this rank's slices onto its GPU.
|
| 119 |
+
# The vLLM loader has resolved/downloaded the model path before this call.
|
| 120 |
+
# Initialize the framework loader's lazy download/timing iterator.
|
| 121 |
+
next(iter(weights), None)
|
| 122 |
+
checkpoint = Path(self.vllm_config.model_config.model)
|
| 123 |
+
if not checkpoint.is_dir():
|
| 124 |
+
from huggingface_hub import snapshot_download
|
| 125 |
+
checkpoint = Path(snapshot_download(self.vllm_config.model_config.model,
|
| 126 |
+
revision=self.vllm_config.model_config.revision))
|
| 127 |
+
index = json.loads((checkpoint/'model.safetensors.index.json').read_text())['weight_map']
|
| 128 |
+
device = torch.device('cuda', torch.cuda.current_device())
|
| 129 |
+
loaded = set()
|
| 130 |
+
for i, layer in enumerate(self.model.layers):
|
| 131 |
+
prefix = f'model.layers.{i}.'
|
| 132 |
+
names = [name for name in index if name.startswith(prefix)]
|
| 133 |
+
shards = {index[name] for name in names}
|
| 134 |
+
assert len(shards) == 1
|
| 135 |
+
with safe_open(checkpoint / next(iter(shards)), framework='pt', device='cpu') as reader:
|
| 136 |
+
if self.config.moe_layer_freq[i]:
|
| 137 |
+
expert_prefix = prefix + 'mlp.experts.'
|
| 138 |
+
sliced = ShardedReader(reader, self.tp_rank, self.tp_size, device)
|
| 139 |
+
with torch.inference_mode(False):
|
| 140 |
+
if self.config.hidden_size >= 4096:
|
| 141 |
+
expert_module = FusedNVFP4Experts(sliced, expert_prefix, self.config.n_routed_experts,
|
| 142 |
+
self.config.hidden_size, self.config.moe_intermediate_size//self.tp_size,
|
| 143 |
+
device, top_k=self.config.num_experts_per_tok,
|
| 144 |
+
max_tokens=self.vllm_config.scheduler_config.max_num_batched_tokens)
|
| 145 |
+
else:
|
| 146 |
+
experts = []
|
| 147 |
+
for expert in range(self.config.n_routed_experts):
|
| 148 |
+
tensors = {p+'.'+kind:sliced.get_tensor(expert_prefix+str(expert)+'.'+p+'.'+kind).to(device)
|
| 149 |
+
for p in ('gate_proj','up_proj','down_proj')
|
| 150 |
+
for kind in ('weight','weight_scale','weight_scale_2','input_scale')}
|
| 151 |
+
experts.append(NVFP4Expert(tensors, 'cutlass'))
|
| 152 |
+
expert_module = StaticReferenceExperts(experts)
|
| 153 |
+
layer.mlp.experts = ReduceExperts(expert_module, self.tp_size)
|
| 154 |
+
loaded.update(name for name in names if name.startswith(expert_prefix))
|
| 155 |
+
for name in names:
|
| 156 |
+
if name in loaded:
|
| 157 |
+
continue
|
| 158 |
+
tensor = reader.get_tensor(name)
|
| 159 |
+
dim = None
|
| 160 |
+
if any('.self_attn.'+key+'.' in name for key in ('q_proj','k_proj','v_proj')):
|
| 161 |
+
dim = 0
|
| 162 |
+
elif '.self_attn.o_proj.weight' in name:
|
| 163 |
+
dim = 1
|
| 164 |
+
elif name.endswith('.self_attn.attention_sink_bias'):
|
| 165 |
+
dim = 0
|
| 166 |
+
elif not self.config.moe_layer_freq[i]:
|
| 167 |
+
if any('.mlp.'+key+'.' in name for key in ('gate_proj','up_proj')):
|
| 168 |
+
dim = 0
|
| 169 |
+
elif '.mlp.down_proj.weight' in name:
|
| 170 |
+
dim = 1
|
| 171 |
+
if dim is not None:
|
| 172 |
+
tensor = tensor.chunk(self.tp_size, dim=dim)[self.tp_rank].contiguous()
|
| 173 |
+
set_module_tensor_to_device(self, name, device, value=tensor, dtype=tensor.dtype)
|
| 174 |
+
loaded.add(name)
|
| 175 |
+
print(f'NAIVE_VLLM_LOADED_LAYER {i+1}/{self.config.num_hidden_layers} TP={self.tp_rank}', flush=True)
|
| 176 |
+
for name in sorted(set(index)-loaded):
|
| 177 |
+
assert name in {'model.embed_tokens.weight','model.norm.weight','lm_head.weight'}
|
| 178 |
+
with safe_open(checkpoint/index[name], framework='pt', device='cpu') as reader:
|
| 179 |
+
tensor = reader.get_tensor(name)
|
| 180 |
+
set_module_tensor_to_device(self, name, device, value=tensor, dtype=tensor.dtype)
|
| 181 |
+
loaded.add(name)
|
| 182 |
+
assert loaded == set(index)
|
| 183 |
+
assert not any(p.is_meta for p in self.parameters())
|
| 184 |
+
self.eval().requires_grad_(False)
|
| 185 |
+
for layer in self.model.layers:
|
| 186 |
+
layer.self_attn.initialize_decode()
|
| 187 |
+
# Parameter names differ for the fused experts; all source tensors were
|
| 188 |
+
# explicitly checked above, so use vLLM's optional return convention.
|
| 189 |
+
return None
|
tokenizer.json
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9871eef5422b8cd120d4ecb00a08dd2f5c939d6dd46af384233a8c5078b224e2
|
| 3 |
+
size 11422840
|
tokenizer_config.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"_comment": "Tokenizer copied from the open-source MiMo 2.5",
|
| 3 |
+
"add_prefix_space": false,
|
| 4 |
+
"backend": "tokenizers",
|
| 5 |
+
"bos_token": null,
|
| 6 |
+
"clean_up_tokenization_spaces": false,
|
| 7 |
+
"eos_token": "<|im_end|>",
|
| 8 |
+
"errors": "replace",
|
| 9 |
+
"extra_special_tokens": [
|
| 10 |
+
"<|im_start|>",
|
| 11 |
+
"<|im_end|>",
|
| 12 |
+
"<|object_ref_start|>",
|
| 13 |
+
"<|object_ref_end|>",
|
| 14 |
+
"<|box_start|>",
|
| 15 |
+
"<|box_end|>",
|
| 16 |
+
"<|quad_start|>",
|
| 17 |
+
"<|quad_end|>",
|
| 18 |
+
"<|vision_start|>",
|
| 19 |
+
"<|vision_end|>",
|
| 20 |
+
"<|vision_pad|>",
|
| 21 |
+
"<|image_pad|>",
|
| 22 |
+
"<|video_pad|>",
|
| 23 |
+
"<|audio_pad|>"
|
| 24 |
+
],
|
| 25 |
+
"is_local": true,
|
| 26 |
+
"local_files_only": false,
|
| 27 |
+
"model_max_length": 1048576,
|
| 28 |
+
"pad_token": "<|endoftext|>",
|
| 29 |
+
"split_special_tokens": false,
|
| 30 |
+
"tokenizer_class": "Qwen2Tokenizer",
|
| 31 |
+
"unk_token": null
|
| 32 |
+
}
|
validation/expert-sharding-tp4-validation.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"checks": [
|
| 4 |
+
{
|
| 5 |
+
"tokens": 1,
|
| 6 |
+
"cosine": 0.9999017715454102,
|
| 7 |
+
"relative_rmse": 0.014022702351212502,
|
| 8 |
+
"max_error": 0.046875
|
| 9 |
+
},
|
| 10 |
+
{
|
| 11 |
+
"tokens": 16,
|
| 12 |
+
"cosine": 0.9999954104423523,
|
| 13 |
+
"relative_rmse": 0.003035087138414383,
|
| 14 |
+
"max_error": 0.03125
|
| 15 |
+
}
|
| 16 |
+
]
|
| 17 |
+
}
|
validation/export-validation.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"tensor_count": 144856,
|
| 4 |
+
"packed_expert_weights": 36096,
|
| 5 |
+
"safetensor_shards": 49,
|
| 6 |
+
"tensor_bytes": 182549965184,
|
| 7 |
+
"all_source_tensors_accounted_for": true
|
| 8 |
+
}
|
validation/native-tiny-graphs-validation.json
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"decode_graphs": true,
|
| 4 |
+
"scope": "Real vLLM V1 engine versus quantized upstream reference, tiny architecture fixture",
|
| 5 |
+
"chunked_prefill": true,
|
| 6 |
+
"prefix_caching": true,
|
| 7 |
+
"max_num_seqs": 2,
|
| 8 |
+
"checks": [
|
| 9 |
+
{
|
| 10 |
+
"prompt_tokens": 8,
|
| 11 |
+
"expected": [
|
| 12 |
+
58,
|
| 13 |
+
193,
|
| 14 |
+
46,
|
| 15 |
+
193,
|
| 16 |
+
46,
|
| 17 |
+
58,
|
| 18 |
+
193,
|
| 19 |
+
46,
|
| 20 |
+
58,
|
| 21 |
+
193,
|
| 22 |
+
46,
|
| 23 |
+
58
|
| 24 |
+
],
|
| 25 |
+
"actual": [
|
| 26 |
+
58,
|
| 27 |
+
193,
|
| 28 |
+
46,
|
| 29 |
+
193,
|
| 30 |
+
46,
|
| 31 |
+
58,
|
| 32 |
+
193,
|
| 33 |
+
46,
|
| 34 |
+
58,
|
| 35 |
+
193,
|
| 36 |
+
46,
|
| 37 |
+
58
|
| 38 |
+
],
|
| 39 |
+
"exact_token_match": true
|
| 40 |
+
},
|
| 41 |
+
{
|
| 42 |
+
"prompt_tokens": 35,
|
| 43 |
+
"expected": [
|
| 44 |
+
193,
|
| 45 |
+
98,
|
| 46 |
+
120,
|
| 47 |
+
46,
|
| 48 |
+
120,
|
| 49 |
+
46,
|
| 50 |
+
120,
|
| 51 |
+
46,
|
| 52 |
+
120,
|
| 53 |
+
46,
|
| 54 |
+
98,
|
| 55 |
+
120
|
| 56 |
+
],
|
| 57 |
+
"actual": [
|
| 58 |
+
193,
|
| 59 |
+
98,
|
| 60 |
+
120,
|
| 61 |
+
46,
|
| 62 |
+
120,
|
| 63 |
+
46,
|
| 64 |
+
120,
|
| 65 |
+
46,
|
| 66 |
+
120,
|
| 67 |
+
46,
|
| 68 |
+
98,
|
| 69 |
+
120
|
| 70 |
+
],
|
| 71 |
+
"exact_token_match": true
|
| 72 |
+
},
|
| 73 |
+
{
|
| 74 |
+
"prompt_tokens": 80,
|
| 75 |
+
"expected": [
|
| 76 |
+
11,
|
| 77 |
+
11,
|
| 78 |
+
11,
|
| 79 |
+
11,
|
| 80 |
+
245,
|
| 81 |
+
11,
|
| 82 |
+
11,
|
| 83 |
+
163,
|
| 84 |
+
11,
|
| 85 |
+
38,
|
| 86 |
+
11,
|
| 87 |
+
245
|
| 88 |
+
],
|
| 89 |
+
"actual": [
|
| 90 |
+
11,
|
| 91 |
+
11,
|
| 92 |
+
11,
|
| 93 |
+
11,
|
| 94 |
+
245,
|
| 95 |
+
11,
|
| 96 |
+
11,
|
| 97 |
+
163,
|
| 98 |
+
11,
|
| 99 |
+
38,
|
| 100 |
+
11,
|
| 101 |
+
245
|
| 102 |
+
],
|
| 103 |
+
"exact_token_match": true
|
| 104 |
+
},
|
| 105 |
+
{
|
| 106 |
+
"prompt_tokens": 17,
|
| 107 |
+
"expected": [
|
| 108 |
+
193,
|
| 109 |
+
197,
|
| 110 |
+
11,
|
| 111 |
+
98,
|
| 112 |
+
120,
|
| 113 |
+
46,
|
| 114 |
+
11,
|
| 115 |
+
46,
|
| 116 |
+
11,
|
| 117 |
+
98,
|
| 118 |
+
120,
|
| 119 |
+
46
|
| 120 |
+
],
|
| 121 |
+
"actual": [
|
| 122 |
+
193,
|
| 123 |
+
197,
|
| 124 |
+
11,
|
| 125 |
+
98,
|
| 126 |
+
120,
|
| 127 |
+
46,
|
| 128 |
+
11,
|
| 129 |
+
46,
|
| 130 |
+
11,
|
| 131 |
+
98,
|
| 132 |
+
120,
|
| 133 |
+
46
|
| 134 |
+
],
|
| 135 |
+
"exact_token_match": true
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"prompt_tokens": 35,
|
| 139 |
+
"expected": [
|
| 140 |
+
193,
|
| 141 |
+
98,
|
| 142 |
+
120,
|
| 143 |
+
46,
|
| 144 |
+
120,
|
| 145 |
+
46,
|
| 146 |
+
120,
|
| 147 |
+
46,
|
| 148 |
+
120,
|
| 149 |
+
46,
|
| 150 |
+
98,
|
| 151 |
+
120
|
| 152 |
+
],
|
| 153 |
+
"actual": [
|
| 154 |
+
193,
|
| 155 |
+
98,
|
| 156 |
+
120,
|
| 157 |
+
46,
|
| 158 |
+
120,
|
| 159 |
+
46,
|
| 160 |
+
120,
|
| 161 |
+
46,
|
| 162 |
+
120,
|
| 163 |
+
46,
|
| 164 |
+
98,
|
| 165 |
+
120
|
| 166 |
+
],
|
| 167 |
+
"exact_token_match": true
|
| 168 |
+
},
|
| 169 |
+
{
|
| 170 |
+
"prompt_tokens": 8,
|
| 171 |
+
"expected": [
|
| 172 |
+
58,
|
| 173 |
+
193,
|
| 174 |
+
46,
|
| 175 |
+
193,
|
| 176 |
+
46,
|
| 177 |
+
58,
|
| 178 |
+
193,
|
| 179 |
+
46,
|
| 180 |
+
58,
|
| 181 |
+
193,
|
| 182 |
+
46,
|
| 183 |
+
58
|
| 184 |
+
],
|
| 185 |
+
"actual": [
|
| 186 |
+
58,
|
| 187 |
+
193,
|
| 188 |
+
46,
|
| 189 |
+
193,
|
| 190 |
+
46,
|
| 191 |
+
58,
|
| 192 |
+
193,
|
| 193 |
+
46,
|
| 194 |
+
58,
|
| 195 |
+
193,
|
| 196 |
+
46,
|
| 197 |
+
58
|
| 198 |
+
],
|
| 199 |
+
"exact_token_match": true
|
| 200 |
+
},
|
| 201 |
+
{
|
| 202 |
+
"prompt_tokens": 8,
|
| 203 |
+
"expected": [
|
| 204 |
+
58,
|
| 205 |
+
193,
|
| 206 |
+
46,
|
| 207 |
+
193,
|
| 208 |
+
46,
|
| 209 |
+
58,
|
| 210 |
+
193,
|
| 211 |
+
46,
|
| 212 |
+
58,
|
| 213 |
+
193,
|
| 214 |
+
46,
|
| 215 |
+
58
|
| 216 |
+
],
|
| 217 |
+
"actual": [
|
| 218 |
+
58,
|
| 219 |
+
193,
|
| 220 |
+
46,
|
| 221 |
+
193,
|
| 222 |
+
46,
|
| 223 |
+
58,
|
| 224 |
+
193,
|
| 225 |
+
46,
|
| 226 |
+
58,
|
| 227 |
+
193,
|
| 228 |
+
46,
|
| 229 |
+
58
|
| 230 |
+
],
|
| 231 |
+
"exact_token_match": true
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"prompt_tokens": 35,
|
| 235 |
+
"expected": [
|
| 236 |
+
193,
|
| 237 |
+
98,
|
| 238 |
+
120,
|
| 239 |
+
46,
|
| 240 |
+
120,
|
| 241 |
+
46,
|
| 242 |
+
120,
|
| 243 |
+
46,
|
| 244 |
+
120,
|
| 245 |
+
46,
|
| 246 |
+
98,
|
| 247 |
+
120
|
| 248 |
+
],
|
| 249 |
+
"actual": [
|
| 250 |
+
193,
|
| 251 |
+
98,
|
| 252 |
+
120,
|
| 253 |
+
46,
|
| 254 |
+
120,
|
| 255 |
+
46,
|
| 256 |
+
120,
|
| 257 |
+
46,
|
| 258 |
+
120,
|
| 259 |
+
46,
|
| 260 |
+
98,
|
| 261 |
+
120
|
| 262 |
+
],
|
| 263 |
+
"exact_token_match": true
|
| 264 |
+
},
|
| 265 |
+
{
|
| 266 |
+
"prompt_tokens": 80,
|
| 267 |
+
"expected": [
|
| 268 |
+
11,
|
| 269 |
+
11,
|
| 270 |
+
11,
|
| 271 |
+
11,
|
| 272 |
+
245,
|
| 273 |
+
11,
|
| 274 |
+
11,
|
| 275 |
+
163,
|
| 276 |
+
11,
|
| 277 |
+
38,
|
| 278 |
+
11,
|
| 279 |
+
245
|
| 280 |
+
],
|
| 281 |
+
"actual": [
|
| 282 |
+
11,
|
| 283 |
+
11,
|
| 284 |
+
11,
|
| 285 |
+
11,
|
| 286 |
+
245,
|
| 287 |
+
11,
|
| 288 |
+
11,
|
| 289 |
+
163,
|
| 290 |
+
11,
|
| 291 |
+
38,
|
| 292 |
+
11,
|
| 293 |
+
245
|
| 294 |
+
],
|
| 295 |
+
"exact_token_match": true
|
| 296 |
+
},
|
| 297 |
+
{
|
| 298 |
+
"prompt_tokens": 17,
|
| 299 |
+
"expected": [
|
| 300 |
+
193,
|
| 301 |
+
197,
|
| 302 |
+
11,
|
| 303 |
+
98,
|
| 304 |
+
120,
|
| 305 |
+
46,
|
| 306 |
+
11,
|
| 307 |
+
46,
|
| 308 |
+
11,
|
| 309 |
+
98,
|
| 310 |
+
120,
|
| 311 |
+
46
|
| 312 |
+
],
|
| 313 |
+
"actual": [
|
| 314 |
+
193,
|
| 315 |
+
197,
|
| 316 |
+
11,
|
| 317 |
+
98,
|
| 318 |
+
120,
|
| 319 |
+
46,
|
| 320 |
+
11,
|
| 321 |
+
46,
|
| 322 |
+
11,
|
| 323 |
+
98,
|
| 324 |
+
120,
|
| 325 |
+
46
|
| 326 |
+
],
|
| 327 |
+
"exact_token_match": true
|
| 328 |
+
},
|
| 329 |
+
{
|
| 330 |
+
"prompt_tokens": 35,
|
| 331 |
+
"expected": [
|
| 332 |
+
193,
|
| 333 |
+
98,
|
| 334 |
+
120,
|
| 335 |
+
46,
|
| 336 |
+
120,
|
| 337 |
+
46,
|
| 338 |
+
120,
|
| 339 |
+
46,
|
| 340 |
+
120,
|
| 341 |
+
46,
|
| 342 |
+
98,
|
| 343 |
+
120
|
| 344 |
+
],
|
| 345 |
+
"actual": [
|
| 346 |
+
193,
|
| 347 |
+
98,
|
| 348 |
+
120,
|
| 349 |
+
46,
|
| 350 |
+
120,
|
| 351 |
+
46,
|
| 352 |
+
120,
|
| 353 |
+
46,
|
| 354 |
+
120,
|
| 355 |
+
46,
|
| 356 |
+
98,
|
| 357 |
+
120
|
| 358 |
+
],
|
| 359 |
+
"exact_token_match": true
|
| 360 |
+
},
|
| 361 |
+
{
|
| 362 |
+
"prompt_tokens": 8,
|
| 363 |
+
"expected": [
|
| 364 |
+
58,
|
| 365 |
+
193,
|
| 366 |
+
46,
|
| 367 |
+
193,
|
| 368 |
+
46,
|
| 369 |
+
58,
|
| 370 |
+
193,
|
| 371 |
+
46,
|
| 372 |
+
58,
|
| 373 |
+
193,
|
| 374 |
+
46,
|
| 375 |
+
58
|
| 376 |
+
],
|
| 377 |
+
"actual": [
|
| 378 |
+
58,
|
| 379 |
+
193,
|
| 380 |
+
46,
|
| 381 |
+
193,
|
| 382 |
+
46,
|
| 383 |
+
58,
|
| 384 |
+
193,
|
| 385 |
+
46,
|
| 386 |
+
58,
|
| 387 |
+
193,
|
| 388 |
+
46,
|
| 389 |
+
58
|
| 390 |
+
],
|
| 391 |
+
"exact_token_match": true
|
| 392 |
+
}
|
| 393 |
+
]
|
| 394 |
+
}
|
validation/native-vllm-api-validation.json
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"engine": "vLLM 0.28.0",
|
| 4 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 5 |
+
"checks": {
|
| 6 |
+
"arithmetic": {
|
| 7 |
+
"id": "chatcmpl-b57ff21de144f7ca",
|
| 8 |
+
"object": "chat.completion",
|
| 9 |
+
"created": 1790592276,
|
| 10 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 11 |
+
"choices": [
|
| 12 |
+
{
|
| 13 |
+
"index": 0,
|
| 14 |
+
"message": {
|
| 15 |
+
"role": "assistant",
|
| 16 |
+
"content": "\n\n4",
|
| 17 |
+
"refusal": null,
|
| 18 |
+
"annotations": null,
|
| 19 |
+
"audio": null,
|
| 20 |
+
"function_call": null,
|
| 21 |
+
"reasoning": null
|
| 22 |
+
},
|
| 23 |
+
"logprobs": null,
|
| 24 |
+
"finish_reason": "stop",
|
| 25 |
+
"stop_reason": null,
|
| 26 |
+
"token_ids": null,
|
| 27 |
+
"routed_experts": null
|
| 28 |
+
}
|
| 29 |
+
],
|
| 30 |
+
"service_tier": null,
|
| 31 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 32 |
+
"usage": {
|
| 33 |
+
"prompt_tokens": 58,
|
| 34 |
+
"total_tokens": 61,
|
| 35 |
+
"completion_tokens": 3,
|
| 36 |
+
"prompt_tokens_details": null,
|
| 37 |
+
"completion_tokens_details": {
|
| 38 |
+
"reasoning_tokens": 0
|
| 39 |
+
}
|
| 40 |
+
},
|
| 41 |
+
"prompt_logprobs": null,
|
| 42 |
+
"prompt_token_ids": null,
|
| 43 |
+
"prompt_text": null,
|
| 44 |
+
"kv_transfer_params": null,
|
| 45 |
+
"ec_transfer_params": null,
|
| 46 |
+
"metrics": null,
|
| 47 |
+
"elapsed_seconds": 0.10958343200036325,
|
| 48 |
+
"completion_tokens_per_second_including_prefill": 27.376401206252197
|
| 49 |
+
},
|
| 50 |
+
"geography": {
|
| 51 |
+
"id": "chatcmpl-9a328e34a75310ee",
|
| 52 |
+
"object": "chat.completion",
|
| 53 |
+
"created": 1790592276,
|
| 54 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 55 |
+
"choices": [
|
| 56 |
+
{
|
| 57 |
+
"index": 0,
|
| 58 |
+
"message": {
|
| 59 |
+
"role": "assistant",
|
| 60 |
+
"content": "\n\nParis",
|
| 61 |
+
"refusal": null,
|
| 62 |
+
"annotations": null,
|
| 63 |
+
"audio": null,
|
| 64 |
+
"function_call": null,
|
| 65 |
+
"reasoning": null
|
| 66 |
+
},
|
| 67 |
+
"logprobs": null,
|
| 68 |
+
"finish_reason": "stop",
|
| 69 |
+
"stop_reason": null,
|
| 70 |
+
"token_ids": null,
|
| 71 |
+
"routed_experts": null
|
| 72 |
+
}
|
| 73 |
+
],
|
| 74 |
+
"service_tier": null,
|
| 75 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 76 |
+
"usage": {
|
| 77 |
+
"prompt_tokens": 57,
|
| 78 |
+
"total_tokens": 60,
|
| 79 |
+
"completion_tokens": 3,
|
| 80 |
+
"prompt_tokens_details": null,
|
| 81 |
+
"completion_tokens_details": {
|
| 82 |
+
"reasoning_tokens": 0
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"prompt_logprobs": null,
|
| 86 |
+
"prompt_token_ids": null,
|
| 87 |
+
"prompt_text": null,
|
| 88 |
+
"kv_transfer_params": null,
|
| 89 |
+
"ec_transfer_params": null,
|
| 90 |
+
"metrics": null,
|
| 91 |
+
"elapsed_seconds": 0.12031267199927242,
|
| 92 |
+
"completion_tokens_per_second_including_prefill": 24.93502928783879
|
| 93 |
+
},
|
| 94 |
+
"coding": {
|
| 95 |
+
"id": "chatcmpl-a8ad4110a48efbdb",
|
| 96 |
+
"object": "chat.completion",
|
| 97 |
+
"created": 1790592276,
|
| 98 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 99 |
+
"choices": [
|
| 100 |
+
{
|
| 101 |
+
"index": 0,
|
| 102 |
+
"message": {
|
| 103 |
+
"role": "assistant",
|
| 104 |
+
"content": "\n\ndef add(a, b):\n return a + b",
|
| 105 |
+
"refusal": null,
|
| 106 |
+
"annotations": null,
|
| 107 |
+
"audio": null,
|
| 108 |
+
"function_call": null,
|
| 109 |
+
"reasoning": null
|
| 110 |
+
},
|
| 111 |
+
"logprobs": null,
|
| 112 |
+
"finish_reason": "stop",
|
| 113 |
+
"stop_reason": null,
|
| 114 |
+
"token_ids": null,
|
| 115 |
+
"routed_experts": null
|
| 116 |
+
}
|
| 117 |
+
],
|
| 118 |
+
"service_tier": null,
|
| 119 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 120 |
+
"usage": {
|
| 121 |
+
"prompt_tokens": 63,
|
| 122 |
+
"total_tokens": 76,
|
| 123 |
+
"completion_tokens": 13,
|
| 124 |
+
"prompt_tokens_details": null,
|
| 125 |
+
"completion_tokens_details": {
|
| 126 |
+
"reasoning_tokens": 0
|
| 127 |
+
}
|
| 128 |
+
},
|
| 129 |
+
"prompt_logprobs": null,
|
| 130 |
+
"prompt_token_ids": null,
|
| 131 |
+
"prompt_text": null,
|
| 132 |
+
"kv_transfer_params": null,
|
| 133 |
+
"ec_transfer_params": null,
|
| 134 |
+
"metrics": null,
|
| 135 |
+
"elapsed_seconds": 0.3035910079997848,
|
| 136 |
+
"completion_tokens_per_second_including_prefill": 42.82076760326583
|
| 137 |
+
},
|
| 138 |
+
"tools": {
|
| 139 |
+
"id": "chatcmpl-9b641c57e20da9a6",
|
| 140 |
+
"object": "chat.completion",
|
| 141 |
+
"created": 1790592277,
|
| 142 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 143 |
+
"choices": [
|
| 144 |
+
{
|
| 145 |
+
"index": 0,
|
| 146 |
+
"message": {
|
| 147 |
+
"role": "assistant",
|
| 148 |
+
"content": null,
|
| 149 |
+
"refusal": null,
|
| 150 |
+
"annotations": null,
|
| 151 |
+
"audio": null,
|
| 152 |
+
"function_call": null,
|
| 153 |
+
"tool_calls": [
|
| 154 |
+
{
|
| 155 |
+
"id": "chatcmpl-tool-8eeac683e7c34ae0",
|
| 156 |
+
"type": "function",
|
| 157 |
+
"function": {
|
| 158 |
+
"name": "get_weather",
|
| 159 |
+
"arguments": "{\"city\": \"Warsaw\"}"
|
| 160 |
+
}
|
| 161 |
+
}
|
| 162 |
+
],
|
| 163 |
+
"reasoning": null
|
| 164 |
+
},
|
| 165 |
+
"logprobs": null,
|
| 166 |
+
"finish_reason": "tool_calls",
|
| 167 |
+
"stop_reason": null,
|
| 168 |
+
"token_ids": null,
|
| 169 |
+
"routed_experts": null
|
| 170 |
+
}
|
| 171 |
+
],
|
| 172 |
+
"service_tier": null,
|
| 173 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 174 |
+
"usage": {
|
| 175 |
+
"prompt_tokens": 284,
|
| 176 |
+
"total_tokens": 307,
|
| 177 |
+
"completion_tokens": 23,
|
| 178 |
+
"prompt_tokens_details": null,
|
| 179 |
+
"completion_tokens_details": {
|
| 180 |
+
"reasoning_tokens": 0
|
| 181 |
+
}
|
| 182 |
+
},
|
| 183 |
+
"prompt_logprobs": null,
|
| 184 |
+
"prompt_token_ids": null,
|
| 185 |
+
"prompt_text": null,
|
| 186 |
+
"kv_transfer_params": null,
|
| 187 |
+
"ec_transfer_params": null,
|
| 188 |
+
"metrics": null,
|
| 189 |
+
"elapsed_seconds": 0.4892891299969051,
|
| 190 |
+
"completion_tokens_per_second_including_prefill": 47.00697111367563
|
| 191 |
+
},
|
| 192 |
+
"reasoning": {
|
| 193 |
+
"id": "chatcmpl-bebdc22c27f814ba",
|
| 194 |
+
"object": "chat.completion",
|
| 195 |
+
"created": 1790592277,
|
| 196 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 197 |
+
"choices": [
|
| 198 |
+
{
|
| 199 |
+
"index": 0,
|
| 200 |
+
"message": {
|
| 201 |
+
"role": "assistant",
|
| 202 |
+
"content": "\n\n42",
|
| 203 |
+
"refusal": null,
|
| 204 |
+
"annotations": null,
|
| 205 |
+
"audio": null,
|
| 206 |
+
"function_call": null,
|
| 207 |
+
"reasoning": "\nWe need answer simple arithmetic. Need think briefly then give answer. We can just answer 42. Need maybe no extra. Ensure final only answer.\n"
|
| 208 |
+
},
|
| 209 |
+
"logprobs": null,
|
| 210 |
+
"finish_reason": "stop",
|
| 211 |
+
"stop_reason": null,
|
| 212 |
+
"token_ids": null,
|
| 213 |
+
"routed_experts": null
|
| 214 |
+
}
|
| 215 |
+
],
|
| 216 |
+
"service_tier": null,
|
| 217 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 218 |
+
"usage": {
|
| 219 |
+
"prompt_tokens": 57,
|
| 220 |
+
"total_tokens": 95,
|
| 221 |
+
"completion_tokens": 38,
|
| 222 |
+
"prompt_tokens_details": null,
|
| 223 |
+
"completion_tokens_details": {
|
| 224 |
+
"reasoning_tokens": 32
|
| 225 |
+
}
|
| 226 |
+
},
|
| 227 |
+
"prompt_logprobs": null,
|
| 228 |
+
"prompt_token_ids": null,
|
| 229 |
+
"prompt_text": null,
|
| 230 |
+
"kv_transfer_params": null,
|
| 231 |
+
"ec_transfer_params": null,
|
| 232 |
+
"metrics": null,
|
| 233 |
+
"elapsed_seconds": 0.7566590700007509,
|
| 234 |
+
"completion_tokens_per_second_including_prefill": 50.220768515947725
|
| 235 |
+
},
|
| 236 |
+
"longer_context": {
|
| 237 |
+
"id": "chatcmpl-ab4c6172888cf312",
|
| 238 |
+
"object": "chat.completion",
|
| 239 |
+
"created": 1790592278,
|
| 240 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 241 |
+
"choices": [
|
| 242 |
+
{
|
| 243 |
+
"index": 0,
|
| 244 |
+
"message": {
|
| 245 |
+
"role": "assistant",
|
| 246 |
+
"content": "\n\n4",
|
| 247 |
+
"refusal": null,
|
| 248 |
+
"annotations": null,
|
| 249 |
+
"audio": null,
|
| 250 |
+
"function_call": null,
|
| 251 |
+
"reasoning": null
|
| 252 |
+
},
|
| 253 |
+
"logprobs": null,
|
| 254 |
+
"finish_reason": "stop",
|
| 255 |
+
"stop_reason": null,
|
| 256 |
+
"token_ids": null,
|
| 257 |
+
"routed_experts": null
|
| 258 |
+
}
|
| 259 |
+
],
|
| 260 |
+
"service_tier": null,
|
| 261 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 262 |
+
"usage": {
|
| 263 |
+
"prompt_tokens": 3800,
|
| 264 |
+
"total_tokens": 3803,
|
| 265 |
+
"completion_tokens": 3,
|
| 266 |
+
"prompt_tokens_details": null,
|
| 267 |
+
"completion_tokens_details": {
|
| 268 |
+
"reasoning_tokens": 0
|
| 269 |
+
}
|
| 270 |
+
},
|
| 271 |
+
"prompt_logprobs": null,
|
| 272 |
+
"prompt_token_ids": null,
|
| 273 |
+
"prompt_text": null,
|
| 274 |
+
"kv_transfer_params": null,
|
| 275 |
+
"ec_transfer_params": null,
|
| 276 |
+
"metrics": null,
|
| 277 |
+
"elapsed_seconds": 1.0702180820007925,
|
| 278 |
+
"completion_tokens_per_second_including_prefill": 2.8031669904057726
|
| 279 |
+
},
|
| 280 |
+
"gpu_memory": "index, memory.used [MiB], memory.total [MiB]\n0, 86684 MiB, 97887 MiB\n1, 86684 MiB, 97887 MiB\n2, 91002 MiB, 97887 MiB\n3, 86684 MiB, 97887 MiB\n"
|
| 281 |
+
},
|
| 282 |
+
"scope": "Basic generation, coding, tool use and sparse-context smoke checks; not an accuracy benchmark"
|
| 283 |
+
}
|
validation/native-vllm-benchmark-repeat.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
validation/native-vllm-benchmark.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
validation/native-vllm-concurrency-validation.json
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"engine": "vLLM 0.28.0",
|
| 4 |
+
"concurrent_requests": 4,
|
| 5 |
+
"scope": "Concurrent scheduling/cache/output smoke test, not a throughput or accuracy benchmark",
|
| 6 |
+
"results": [
|
| 7 |
+
{
|
| 8 |
+
"id": "chatcmpl-8f7154ae17b91c78",
|
| 9 |
+
"object": "chat.completion",
|
| 10 |
+
"created": 1790592282,
|
| 11 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 12 |
+
"choices": [
|
| 13 |
+
{
|
| 14 |
+
"index": 0,
|
| 15 |
+
"message": {
|
| 16 |
+
"role": "assistant",
|
| 17 |
+
"content": "\n\n23\n\nTo add 20 and 3, you can think of it as combining two quantities. Start with the number 20, which represents two tens. Then, add 3 more to it. One simple way is to count forward: begin at 20 and count three steps: 21, 22, 23. Alternatively, you can break it down by place value. The number 20 has a 2 in the tens place and a 0 in the ones place. The number 3 has a 3 in the ones place. When you add them, you add the ones first: 0 + 3 = 3. Then, you add the tens: 2 + 0 = 2. Combining these gives you 2 tens and 3 ones, which is 23. This method works because you are simply combining the values in each place without any carrying",
|
| 18 |
+
"refusal": null,
|
| 19 |
+
"annotations": null,
|
| 20 |
+
"audio": null,
|
| 21 |
+
"function_call": null,
|
| 22 |
+
"reasoning": null
|
| 23 |
+
},
|
| 24 |
+
"logprobs": null,
|
| 25 |
+
"finish_reason": "length",
|
| 26 |
+
"stop_reason": null,
|
| 27 |
+
"token_ids": null,
|
| 28 |
+
"routed_experts": null
|
| 29 |
+
}
|
| 30 |
+
],
|
| 31 |
+
"service_tier": null,
|
| 32 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 33 |
+
"usage": {
|
| 34 |
+
"prompt_tokens": 78,
|
| 35 |
+
"total_tokens": 270,
|
| 36 |
+
"completion_tokens": 192,
|
| 37 |
+
"prompt_tokens_details": null,
|
| 38 |
+
"completion_tokens_details": {
|
| 39 |
+
"reasoning_tokens": 0
|
| 40 |
+
}
|
| 41 |
+
},
|
| 42 |
+
"prompt_logprobs": null,
|
| 43 |
+
"prompt_token_ids": null,
|
| 44 |
+
"prompt_text": null,
|
| 45 |
+
"kv_transfer_params": null,
|
| 46 |
+
"ec_transfer_params": null,
|
| 47 |
+
"metrics": null,
|
| 48 |
+
"elapsed_seconds": 25.521290875003615,
|
| 49 |
+
"completion_tokens_per_second_including_prefill": 7.523130430210764
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"id": "chatcmpl-b6950169c10c14bf",
|
| 53 |
+
"object": "chat.completion",
|
| 54 |
+
"created": 1790592282,
|
| 55 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 56 |
+
"choices": [
|
| 57 |
+
{
|
| 58 |
+
"index": 0,
|
| 59 |
+
"message": {
|
| 60 |
+
"role": "assistant",
|
| 61 |
+
"content": "\n\n25\n\nTo add 20 and 5, you can think of it as combining two quantities. Start with the number 20, which represents two groups of ten. Then, add 5 more to it. One simple way to visualize this is to count forward from 20: 21, 22, 23, 24, 25. After five steps, you land on 25. Alternatively, you can break the numbers down by place value. The number 20 has a 2 in the tens place and a 0 in the ones place. The number 5 has a 5 in the ones place. When you add them, you add the ones digits: 0 + 5 = 5. The tens digit remains 2, since there is no other tens digit to add. So, you get 2 in the tens place and 5 in the",
|
| 62 |
+
"refusal": null,
|
| 63 |
+
"annotations": null,
|
| 64 |
+
"audio": null,
|
| 65 |
+
"function_call": null,
|
| 66 |
+
"reasoning": null
|
| 67 |
+
},
|
| 68 |
+
"logprobs": null,
|
| 69 |
+
"finish_reason": "length",
|
| 70 |
+
"stop_reason": null,
|
| 71 |
+
"token_ids": null,
|
| 72 |
+
"routed_experts": null
|
| 73 |
+
}
|
| 74 |
+
],
|
| 75 |
+
"service_tier": null,
|
| 76 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 77 |
+
"usage": {
|
| 78 |
+
"prompt_tokens": 78,
|
| 79 |
+
"total_tokens": 270,
|
| 80 |
+
"completion_tokens": 192,
|
| 81 |
+
"prompt_tokens_details": null,
|
| 82 |
+
"completion_tokens_details": {
|
| 83 |
+
"reasoning_tokens": 0
|
| 84 |
+
}
|
| 85 |
+
},
|
| 86 |
+
"prompt_logprobs": null,
|
| 87 |
+
"prompt_token_ids": null,
|
| 88 |
+
"prompt_text": null,
|
| 89 |
+
"kv_transfer_params": null,
|
| 90 |
+
"ec_transfer_params": null,
|
| 91 |
+
"metrics": null,
|
| 92 |
+
"elapsed_seconds": 23.55511791400204,
|
| 93 |
+
"completion_tokens_per_second_including_prefill": 8.151094836416338
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"id": "chatcmpl-ae5bdf320cff8063",
|
| 97 |
+
"object": "chat.completion",
|
| 98 |
+
"created": 1790592282,
|
| 99 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 100 |
+
"choices": [
|
| 101 |
+
{
|
| 102 |
+
"index": 0,
|
| 103 |
+
"message": {
|
| 104 |
+
"role": "assistant",
|
| 105 |
+
"content": "\n\n27\n\nTo add 20 and 7, you can think of it as combining two quantities. Start with the number 20, which represents two groups of ten. Then, add 7 more to it. One simple way is to count up from 20: 21, 22, 23, 24, 25, 26, 27. After seven steps, you land on 27. Another method is to break 20 into 10 and 10, then add 7 to one of the tens to get 17, and finally add the other 10 to reach 27. You can also use place value: 20 has a 2 in the tens place and a 0 in the ones place. Adding 7 affects only the ones place, so 0 + 7 = 7, while the",
|
| 106 |
+
"refusal": null,
|
| 107 |
+
"annotations": null,
|
| 108 |
+
"audio": null,
|
| 109 |
+
"function_call": null,
|
| 110 |
+
"reasoning": null
|
| 111 |
+
},
|
| 112 |
+
"logprobs": null,
|
| 113 |
+
"finish_reason": "length",
|
| 114 |
+
"stop_reason": null,
|
| 115 |
+
"token_ids": null,
|
| 116 |
+
"routed_experts": null
|
| 117 |
+
}
|
| 118 |
+
],
|
| 119 |
+
"service_tier": null,
|
| 120 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 121 |
+
"usage": {
|
| 122 |
+
"prompt_tokens": 78,
|
| 123 |
+
"total_tokens": 270,
|
| 124 |
+
"completion_tokens": 192,
|
| 125 |
+
"prompt_tokens_details": null,
|
| 126 |
+
"completion_tokens_details": {
|
| 127 |
+
"reasoning_tokens": 0
|
| 128 |
+
}
|
| 129 |
+
},
|
| 130 |
+
"prompt_logprobs": null,
|
| 131 |
+
"prompt_token_ids": null,
|
| 132 |
+
"prompt_text": null,
|
| 133 |
+
"kv_transfer_params": null,
|
| 134 |
+
"ec_transfer_params": null,
|
| 135 |
+
"metrics": null,
|
| 136 |
+
"elapsed_seconds": 23.458772466001392,
|
| 137 |
+
"completion_tokens_per_second_including_prefill": 8.184571476545248
|
| 138 |
+
},
|
| 139 |
+
{
|
| 140 |
+
"id": "chatcmpl-a7f84a9ffb302b3b",
|
| 141 |
+
"object": "chat.completion",
|
| 142 |
+
"created": 1790592282,
|
| 143 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 144 |
+
"choices": [
|
| 145 |
+
{
|
| 146 |
+
"index": 0,
|
| 147 |
+
"message": {
|
| 148 |
+
"role": "assistant",
|
| 149 |
+
"content": "\n\n29\n\nTo add 20 and 9, you can think of it as combining two groups of objects. Imagine you have 20 apples in one basket and 9 apples in another basket. If you pour all the apples together into a single large container, you would count them one by one to find the total. Starting with the 20 apples, you would count 21, 22, 23, 24, 25, 26, 27, 28, and finally 29. This process of counting upward from 20 by nine steps gives you the answer. Alternatively, you can use place value: 20 is two tens and zero ones, while 9 is zero tens and nine ones. Adding the ones together gives 0 + 9 = 9, and adding the tens gives 2 + 0 = 2 tens, which",
|
| 150 |
+
"refusal": null,
|
| 151 |
+
"annotations": null,
|
| 152 |
+
"audio": null,
|
| 153 |
+
"function_call": null,
|
| 154 |
+
"reasoning": null
|
| 155 |
+
},
|
| 156 |
+
"logprobs": null,
|
| 157 |
+
"finish_reason": "length",
|
| 158 |
+
"stop_reason": null,
|
| 159 |
+
"token_ids": null,
|
| 160 |
+
"routed_experts": null
|
| 161 |
+
}
|
| 162 |
+
],
|
| 163 |
+
"service_tier": null,
|
| 164 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b",
|
| 165 |
+
"usage": {
|
| 166 |
+
"prompt_tokens": 78,
|
| 167 |
+
"total_tokens": 270,
|
| 168 |
+
"completion_tokens": 192,
|
| 169 |
+
"prompt_tokens_details": null,
|
| 170 |
+
"completion_tokens_details": {
|
| 171 |
+
"reasoning_tokens": 0
|
| 172 |
+
}
|
| 173 |
+
},
|
| 174 |
+
"prompt_logprobs": null,
|
| 175 |
+
"prompt_token_ids": null,
|
| 176 |
+
"prompt_text": null,
|
| 177 |
+
"kv_transfer_params": null,
|
| 178 |
+
"ec_transfer_params": null,
|
| 179 |
+
"metrics": null,
|
| 180 |
+
"elapsed_seconds": 25.521558972002822,
|
| 181 |
+
"completion_tokens_per_second_including_prefill": 7.523051401782478
|
| 182 |
+
}
|
| 183 |
+
]
|
| 184 |
+
}
|
validation/native-vllm-streaming-validation.json
ADDED
|
@@ -0,0 +1,1493 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"engine": "vLLM 0.28.0",
|
| 4 |
+
"tool_call": {
|
| 5 |
+
"request": {
|
| 6 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 7 |
+
"messages": [
|
| 8 |
+
{
|
| 9 |
+
"role": "user",
|
| 10 |
+
"content": "Call get_weather for Warsaw. Do not answer from memory."
|
| 11 |
+
}
|
| 12 |
+
],
|
| 13 |
+
"temperature": 0,
|
| 14 |
+
"max_tokens": 256,
|
| 15 |
+
"stream": true,
|
| 16 |
+
"stream_options": {
|
| 17 |
+
"include_usage": true
|
| 18 |
+
},
|
| 19 |
+
"return_token_ids": true,
|
| 20 |
+
"chat_template_kwargs": {
|
| 21 |
+
"enable_thinking": false
|
| 22 |
+
},
|
| 23 |
+
"tools": [
|
| 24 |
+
{
|
| 25 |
+
"type": "function",
|
| 26 |
+
"function": {
|
| 27 |
+
"name": "get_weather",
|
| 28 |
+
"description": "Get weather for a city",
|
| 29 |
+
"parameters": {
|
| 30 |
+
"type": "object",
|
| 31 |
+
"properties": {
|
| 32 |
+
"city": {
|
| 33 |
+
"type": "string"
|
| 34 |
+
}
|
| 35 |
+
},
|
| 36 |
+
"required": [
|
| 37 |
+
"city"
|
| 38 |
+
]
|
| 39 |
+
}
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
],
|
| 43 |
+
"tool_choice": "auto"
|
| 44 |
+
},
|
| 45 |
+
"content": "",
|
| 46 |
+
"reasoning": "",
|
| 47 |
+
"tool_calls": {
|
| 48 |
+
"0": {
|
| 49 |
+
"name": "get_weather",
|
| 50 |
+
"arguments": "{\"city\": \"Warsaw\"}"
|
| 51 |
+
}
|
| 52 |
+
},
|
| 53 |
+
"usage": {
|
| 54 |
+
"prompt_tokens": 282,
|
| 55 |
+
"total_tokens": 305,
|
| 56 |
+
"completion_tokens": 23,
|
| 57 |
+
"completion_tokens_details": {
|
| 58 |
+
"reasoning_tokens": 0
|
| 59 |
+
}
|
| 60 |
+
},
|
| 61 |
+
"events": [
|
| 62 |
+
{
|
| 63 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 64 |
+
"object": "chat.completion.chunk",
|
| 65 |
+
"created": 1790592279,
|
| 66 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 67 |
+
"choices": [
|
| 68 |
+
{
|
| 69 |
+
"index": 0,
|
| 70 |
+
"delta": {
|
| 71 |
+
"role": "assistant",
|
| 72 |
+
"content": ""
|
| 73 |
+
},
|
| 74 |
+
"logprobs": null,
|
| 75 |
+
"finish_reason": null
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"prompt_token_ids": [
|
| 79 |
+
151644,
|
| 80 |
+
8948,
|
| 81 |
+
198,
|
| 82 |
+
25139,
|
| 83 |
+
287,
|
| 84 |
+
30022,
|
| 85 |
+
371,
|
| 86 |
+
25,
|
| 87 |
+
7487,
|
| 88 |
+
151645,
|
| 89 |
+
151644,
|
| 90 |
+
8948,
|
| 91 |
+
198,
|
| 92 |
+
2610,
|
| 93 |
+
525,
|
| 94 |
+
12812,
|
| 95 |
+
533,
|
| 96 |
+
11250,
|
| 97 |
+
15,
|
| 98 |
+
13,
|
| 99 |
+
20,
|
| 100 |
+
12,
|
| 101 |
+
23876,
|
| 102 |
+
11,
|
| 103 |
+
264,
|
| 104 |
+
10950,
|
| 105 |
+
15235,
|
| 106 |
+
17847,
|
| 107 |
+
44936,
|
| 108 |
+
553,
|
| 109 |
+
12812,
|
| 110 |
+
533,
|
| 111 |
+
15235,
|
| 112 |
+
382,
|
| 113 |
+
2,
|
| 114 |
+
13852,
|
| 115 |
+
271,
|
| 116 |
+
2610,
|
| 117 |
+
1231,
|
| 118 |
+
1618,
|
| 119 |
+
825,
|
| 120 |
+
476,
|
| 121 |
+
803,
|
| 122 |
+
5746,
|
| 123 |
+
311,
|
| 124 |
+
7789,
|
| 125 |
+
448,
|
| 126 |
+
279,
|
| 127 |
+
1196,
|
| 128 |
+
3239,
|
| 129 |
+
382,
|
| 130 |
+
2610,
|
| 131 |
+
614,
|
| 132 |
+
2615,
|
| 133 |
+
311,
|
| 134 |
+
279,
|
| 135 |
+
2701,
|
| 136 |
+
5746,
|
| 137 |
+
1447,
|
| 138 |
+
27,
|
| 139 |
+
15918,
|
| 140 |
+
397,
|
| 141 |
+
27,
|
| 142 |
+
1688,
|
| 143 |
+
397,
|
| 144 |
+
27,
|
| 145 |
+
606,
|
| 146 |
+
29,
|
| 147 |
+
455,
|
| 148 |
+
69364,
|
| 149 |
+
522,
|
| 150 |
+
606,
|
| 151 |
+
397,
|
| 152 |
+
27,
|
| 153 |
+
4684,
|
| 154 |
+
29,
|
| 155 |
+
1949,
|
| 156 |
+
9104,
|
| 157 |
+
369,
|
| 158 |
+
264,
|
| 159 |
+
3283,
|
| 160 |
+
522,
|
| 161 |
+
4684,
|
| 162 |
+
397,
|
| 163 |
+
27,
|
| 164 |
+
13786,
|
| 165 |
+
397,
|
| 166 |
+
27,
|
| 167 |
+
16181,
|
| 168 |
+
397,
|
| 169 |
+
27,
|
| 170 |
+
606,
|
| 171 |
+
29,
|
| 172 |
+
8926,
|
| 173 |
+
522,
|
| 174 |
+
606,
|
| 175 |
+
397,
|
| 176 |
+
27,
|
| 177 |
+
1313,
|
| 178 |
+
29,
|
| 179 |
+
917,
|
| 180 |
+
522,
|
| 181 |
+
1313,
|
| 182 |
+
397,
|
| 183 |
+
522,
|
| 184 |
+
16181,
|
| 185 |
+
397,
|
| 186 |
+
27,
|
| 187 |
+
6279,
|
| 188 |
+
29,
|
| 189 |
+
1183,
|
| 190 |
+
8926,
|
| 191 |
+
1341,
|
| 192 |
+
522,
|
| 193 |
+
6279,
|
| 194 |
+
397,
|
| 195 |
+
522,
|
| 196 |
+
13786,
|
| 197 |
+
397,
|
| 198 |
+
522,
|
| 199 |
+
1688,
|
| 200 |
+
397,
|
| 201 |
+
522,
|
| 202 |
+
15918,
|
| 203 |
+
1339,
|
| 204 |
+
2461,
|
| 205 |
+
1817,
|
| 206 |
+
729,
|
| 207 |
+
1618,
|
| 208 |
+
11,
|
| 209 |
+
2550,
|
| 210 |
+
279,
|
| 211 |
+
729,
|
| 212 |
+
829,
|
| 213 |
+
323,
|
| 214 |
+
5977,
|
| 215 |
+
304,
|
| 216 |
+
279,
|
| 217 |
+
2701,
|
| 218 |
+
3561,
|
| 219 |
+
510,
|
| 220 |
+
151657,
|
| 221 |
+
198,
|
| 222 |
+
27,
|
| 223 |
+
1688,
|
| 224 |
+
28,
|
| 225 |
+
8687,
|
| 226 |
+
9174,
|
| 227 |
+
1269,
|
| 228 |
+
397,
|
| 229 |
+
27,
|
| 230 |
+
16181,
|
| 231 |
+
28,
|
| 232 |
+
8687,
|
| 233 |
+
24899,
|
| 234 |
+
62,
|
| 235 |
+
16,
|
| 236 |
+
29,
|
| 237 |
+
957,
|
| 238 |
+
62,
|
| 239 |
+
16,
|
| 240 |
+
522,
|
| 241 |
+
16181,
|
| 242 |
+
397,
|
| 243 |
+
27,
|
| 244 |
+
16181,
|
| 245 |
+
28,
|
| 246 |
+
8687,
|
| 247 |
+
24899,
|
| 248 |
+
62,
|
| 249 |
+
17,
|
| 250 |
+
41993,
|
| 251 |
+
374,
|
| 252 |
+
279,
|
| 253 |
+
897,
|
| 254 |
+
369,
|
| 255 |
+
279,
|
| 256 |
+
2086,
|
| 257 |
+
5733,
|
| 258 |
+
198,
|
| 259 |
+
9033,
|
| 260 |
+
646,
|
| 261 |
+
9390,
|
| 262 |
+
198,
|
| 263 |
+
35673,
|
| 264 |
+
5128,
|
| 265 |
+
522,
|
| 266 |
+
16181,
|
| 267 |
+
397,
|
| 268 |
+
522,
|
| 269 |
+
1688,
|
| 270 |
+
397,
|
| 271 |
+
151658,
|
| 272 |
+
271,
|
| 273 |
+
27,
|
| 274 |
+
98743,
|
| 275 |
+
397,
|
| 276 |
+
12,
|
| 277 |
+
5712,
|
| 278 |
+
6738,
|
| 279 |
+
27732,
|
| 280 |
+
1795,
|
| 281 |
+
279,
|
| 282 |
+
5189,
|
| 283 |
+
3561,
|
| 284 |
+
25,
|
| 285 |
+
458,
|
| 286 |
+
9179,
|
| 287 |
+
366,
|
| 288 |
+
1688,
|
| 289 |
+
28,
|
| 290 |
+
1112,
|
| 291 |
+
1472,
|
| 292 |
+
1688,
|
| 293 |
+
29,
|
| 294 |
+
2504,
|
| 295 |
+
1969,
|
| 296 |
+
387,
|
| 297 |
+
24034,
|
| 298 |
+
2878,
|
| 299 |
+
220,
|
| 300 |
+
151657,
|
| 301 |
+
151658,
|
| 302 |
+
11874,
|
| 303 |
+
9492,
|
| 304 |
+
198,
|
| 305 |
+
12,
|
| 306 |
+
9319,
|
| 307 |
+
4183,
|
| 308 |
+
990,
|
| 309 |
+
729,
|
| 310 |
+
6738,
|
| 311 |
+
4766,
|
| 312 |
+
220,
|
| 313 |
+
151667,
|
| 314 |
+
151668,
|
| 315 |
+
9492,
|
| 316 |
+
624,
|
| 317 |
+
12,
|
| 318 |
+
576,
|
| 319 |
+
897,
|
| 320 |
+
43810,
|
| 321 |
+
1948,
|
| 322 |
+
5733,
|
| 323 |
+
9492,
|
| 324 |
+
374,
|
| 325 |
+
33583,
|
| 326 |
+
6896,
|
| 327 |
+
438,
|
| 328 |
+
30430,
|
| 329 |
+
11,
|
| 330 |
+
2670,
|
| 331 |
+
501,
|
| 332 |
+
7969,
|
| 333 |
+
323,
|
| 334 |
+
12621,
|
| 335 |
+
624,
|
| 336 |
+
522,
|
| 337 |
+
98743,
|
| 338 |
+
29,
|
| 339 |
+
151645,
|
| 340 |
+
151644,
|
| 341 |
+
872,
|
| 342 |
+
198,
|
| 343 |
+
7220,
|
| 344 |
+
633,
|
| 345 |
+
69364,
|
| 346 |
+
369,
|
| 347 |
+
72176,
|
| 348 |
+
13,
|
| 349 |
+
3155,
|
| 350 |
+
537,
|
| 351 |
+
4226,
|
| 352 |
+
504,
|
| 353 |
+
4938,
|
| 354 |
+
13,
|
| 355 |
+
151645,
|
| 356 |
+
151644,
|
| 357 |
+
77091,
|
| 358 |
+
198,
|
| 359 |
+
151667,
|
| 360 |
+
151668
|
| 361 |
+
],
|
| 362 |
+
"prompt_text": null
|
| 363 |
+
},
|
| 364 |
+
{
|
| 365 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 366 |
+
"object": "chat.completion.chunk",
|
| 367 |
+
"created": 1790592279,
|
| 368 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 369 |
+
"choices": [
|
| 370 |
+
{
|
| 371 |
+
"index": 0,
|
| 372 |
+
"delta": {},
|
| 373 |
+
"logprobs": null,
|
| 374 |
+
"finish_reason": null,
|
| 375 |
+
"token_ids": [
|
| 376 |
+
271
|
| 377 |
+
]
|
| 378 |
+
}
|
| 379 |
+
]
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 383 |
+
"object": "chat.completion.chunk",
|
| 384 |
+
"created": 1790592279,
|
| 385 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 386 |
+
"choices": [
|
| 387 |
+
{
|
| 388 |
+
"index": 0,
|
| 389 |
+
"delta": {},
|
| 390 |
+
"logprobs": null,
|
| 391 |
+
"finish_reason": null,
|
| 392 |
+
"token_ids": [
|
| 393 |
+
151657
|
| 394 |
+
]
|
| 395 |
+
}
|
| 396 |
+
]
|
| 397 |
+
},
|
| 398 |
+
{
|
| 399 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 400 |
+
"object": "chat.completion.chunk",
|
| 401 |
+
"created": 1790592279,
|
| 402 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 403 |
+
"choices": [
|
| 404 |
+
{
|
| 405 |
+
"index": 0,
|
| 406 |
+
"delta": {},
|
| 407 |
+
"logprobs": null,
|
| 408 |
+
"finish_reason": null,
|
| 409 |
+
"token_ids": [
|
| 410 |
+
198
|
| 411 |
+
]
|
| 412 |
+
}
|
| 413 |
+
]
|
| 414 |
+
},
|
| 415 |
+
{
|
| 416 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 417 |
+
"object": "chat.completion.chunk",
|
| 418 |
+
"created": 1790592279,
|
| 419 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 420 |
+
"choices": [
|
| 421 |
+
{
|
| 422 |
+
"index": 0,
|
| 423 |
+
"delta": {},
|
| 424 |
+
"logprobs": null,
|
| 425 |
+
"finish_reason": null,
|
| 426 |
+
"token_ids": [
|
| 427 |
+
27
|
| 428 |
+
]
|
| 429 |
+
}
|
| 430 |
+
]
|
| 431 |
+
},
|
| 432 |
+
{
|
| 433 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 434 |
+
"object": "chat.completion.chunk",
|
| 435 |
+
"created": 1790592279,
|
| 436 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 437 |
+
"choices": [
|
| 438 |
+
{
|
| 439 |
+
"index": 0,
|
| 440 |
+
"delta": {},
|
| 441 |
+
"logprobs": null,
|
| 442 |
+
"finish_reason": null,
|
| 443 |
+
"token_ids": [
|
| 444 |
+
1688
|
| 445 |
+
]
|
| 446 |
+
}
|
| 447 |
+
]
|
| 448 |
+
},
|
| 449 |
+
{
|
| 450 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 451 |
+
"object": "chat.completion.chunk",
|
| 452 |
+
"created": 1790592279,
|
| 453 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 454 |
+
"choices": [
|
| 455 |
+
{
|
| 456 |
+
"index": 0,
|
| 457 |
+
"delta": {},
|
| 458 |
+
"logprobs": null,
|
| 459 |
+
"finish_reason": null,
|
| 460 |
+
"token_ids": [
|
| 461 |
+
28280
|
| 462 |
+
]
|
| 463 |
+
}
|
| 464 |
+
]
|
| 465 |
+
},
|
| 466 |
+
{
|
| 467 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 468 |
+
"object": "chat.completion.chunk",
|
| 469 |
+
"created": 1790592279,
|
| 470 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 471 |
+
"choices": [
|
| 472 |
+
{
|
| 473 |
+
"index": 0,
|
| 474 |
+
"delta": {},
|
| 475 |
+
"logprobs": null,
|
| 476 |
+
"finish_reason": null,
|
| 477 |
+
"token_ids": [
|
| 478 |
+
69364
|
| 479 |
+
]
|
| 480 |
+
}
|
| 481 |
+
]
|
| 482 |
+
},
|
| 483 |
+
{
|
| 484 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 485 |
+
"object": "chat.completion.chunk",
|
| 486 |
+
"created": 1790592279,
|
| 487 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 488 |
+
"choices": [
|
| 489 |
+
{
|
| 490 |
+
"index": 0,
|
| 491 |
+
"delta": {
|
| 492 |
+
"tool_calls": [
|
| 493 |
+
{
|
| 494 |
+
"id": "chatcmpl-tool-b7a4891d78286e7f",
|
| 495 |
+
"type": "function",
|
| 496 |
+
"index": 0,
|
| 497 |
+
"function": {
|
| 498 |
+
"name": "get_weather"
|
| 499 |
+
}
|
| 500 |
+
}
|
| 501 |
+
]
|
| 502 |
+
},
|
| 503 |
+
"logprobs": null,
|
| 504 |
+
"finish_reason": null,
|
| 505 |
+
"token_ids": [
|
| 506 |
+
397
|
| 507 |
+
]
|
| 508 |
+
}
|
| 509 |
+
]
|
| 510 |
+
},
|
| 511 |
+
{
|
| 512 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 513 |
+
"object": "chat.completion.chunk",
|
| 514 |
+
"created": 1790592279,
|
| 515 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 516 |
+
"choices": [
|
| 517 |
+
{
|
| 518 |
+
"index": 0,
|
| 519 |
+
"delta": {},
|
| 520 |
+
"logprobs": null,
|
| 521 |
+
"finish_reason": null,
|
| 522 |
+
"token_ids": [
|
| 523 |
+
27
|
| 524 |
+
]
|
| 525 |
+
}
|
| 526 |
+
]
|
| 527 |
+
},
|
| 528 |
+
{
|
| 529 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 530 |
+
"object": "chat.completion.chunk",
|
| 531 |
+
"created": 1790592279,
|
| 532 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 533 |
+
"choices": [
|
| 534 |
+
{
|
| 535 |
+
"index": 0,
|
| 536 |
+
"delta": {},
|
| 537 |
+
"logprobs": null,
|
| 538 |
+
"finish_reason": null,
|
| 539 |
+
"token_ids": [
|
| 540 |
+
16181
|
| 541 |
+
]
|
| 542 |
+
}
|
| 543 |
+
]
|
| 544 |
+
},
|
| 545 |
+
{
|
| 546 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 547 |
+
"object": "chat.completion.chunk",
|
| 548 |
+
"created": 1790592279,
|
| 549 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 550 |
+
"choices": [
|
| 551 |
+
{
|
| 552 |
+
"index": 0,
|
| 553 |
+
"delta": {},
|
| 554 |
+
"logprobs": null,
|
| 555 |
+
"finish_reason": null,
|
| 556 |
+
"token_ids": [
|
| 557 |
+
28
|
| 558 |
+
]
|
| 559 |
+
}
|
| 560 |
+
]
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 564 |
+
"object": "chat.completion.chunk",
|
| 565 |
+
"created": 1790592279,
|
| 566 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 567 |
+
"choices": [
|
| 568 |
+
{
|
| 569 |
+
"index": 0,
|
| 570 |
+
"delta": {},
|
| 571 |
+
"logprobs": null,
|
| 572 |
+
"finish_reason": null,
|
| 573 |
+
"token_ids": [
|
| 574 |
+
8926
|
| 575 |
+
]
|
| 576 |
+
}
|
| 577 |
+
]
|
| 578 |
+
},
|
| 579 |
+
{
|
| 580 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 581 |
+
"object": "chat.completion.chunk",
|
| 582 |
+
"created": 1790592279,
|
| 583 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 584 |
+
"choices": [
|
| 585 |
+
{
|
| 586 |
+
"index": 0,
|
| 587 |
+
"delta": {
|
| 588 |
+
"tool_calls": [
|
| 589 |
+
{
|
| 590 |
+
"index": 0,
|
| 591 |
+
"function": {
|
| 592 |
+
"arguments": "{\"city\": \""
|
| 593 |
+
}
|
| 594 |
+
}
|
| 595 |
+
]
|
| 596 |
+
},
|
| 597 |
+
"logprobs": null,
|
| 598 |
+
"finish_reason": null,
|
| 599 |
+
"token_ids": [
|
| 600 |
+
29
|
| 601 |
+
]
|
| 602 |
+
}
|
| 603 |
+
]
|
| 604 |
+
},
|
| 605 |
+
{
|
| 606 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 607 |
+
"object": "chat.completion.chunk",
|
| 608 |
+
"created": 1790592279,
|
| 609 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 610 |
+
"choices": [
|
| 611 |
+
{
|
| 612 |
+
"index": 0,
|
| 613 |
+
"delta": {
|
| 614 |
+
"tool_calls": [
|
| 615 |
+
{
|
| 616 |
+
"index": 0,
|
| 617 |
+
"function": {
|
| 618 |
+
"arguments": "Wars"
|
| 619 |
+
}
|
| 620 |
+
}
|
| 621 |
+
]
|
| 622 |
+
},
|
| 623 |
+
"logprobs": null,
|
| 624 |
+
"finish_reason": null,
|
| 625 |
+
"token_ids": [
|
| 626 |
+
98970
|
| 627 |
+
]
|
| 628 |
+
}
|
| 629 |
+
]
|
| 630 |
+
},
|
| 631 |
+
{
|
| 632 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 633 |
+
"object": "chat.completion.chunk",
|
| 634 |
+
"created": 1790592279,
|
| 635 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 636 |
+
"choices": [
|
| 637 |
+
{
|
| 638 |
+
"index": 0,
|
| 639 |
+
"delta": {
|
| 640 |
+
"tool_calls": [
|
| 641 |
+
{
|
| 642 |
+
"index": 0,
|
| 643 |
+
"function": {
|
| 644 |
+
"arguments": "aw"
|
| 645 |
+
}
|
| 646 |
+
}
|
| 647 |
+
]
|
| 648 |
+
},
|
| 649 |
+
"logprobs": null,
|
| 650 |
+
"finish_reason": null,
|
| 651 |
+
"token_ids": [
|
| 652 |
+
672
|
| 653 |
+
]
|
| 654 |
+
}
|
| 655 |
+
]
|
| 656 |
+
},
|
| 657 |
+
{
|
| 658 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 659 |
+
"object": "chat.completion.chunk",
|
| 660 |
+
"created": 1790592279,
|
| 661 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 662 |
+
"choices": [
|
| 663 |
+
{
|
| 664 |
+
"index": 0,
|
| 665 |
+
"delta": {},
|
| 666 |
+
"logprobs": null,
|
| 667 |
+
"finish_reason": null,
|
| 668 |
+
"token_ids": [
|
| 669 |
+
522
|
| 670 |
+
]
|
| 671 |
+
}
|
| 672 |
+
]
|
| 673 |
+
},
|
| 674 |
+
{
|
| 675 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 676 |
+
"object": "chat.completion.chunk",
|
| 677 |
+
"created": 1790592279,
|
| 678 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 679 |
+
"choices": [
|
| 680 |
+
{
|
| 681 |
+
"index": 0,
|
| 682 |
+
"delta": {},
|
| 683 |
+
"logprobs": null,
|
| 684 |
+
"finish_reason": null,
|
| 685 |
+
"token_ids": [
|
| 686 |
+
16181
|
| 687 |
+
]
|
| 688 |
+
}
|
| 689 |
+
]
|
| 690 |
+
},
|
| 691 |
+
{
|
| 692 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 693 |
+
"object": "chat.completion.chunk",
|
| 694 |
+
"created": 1790592279,
|
| 695 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 696 |
+
"choices": [
|
| 697 |
+
{
|
| 698 |
+
"index": 0,
|
| 699 |
+
"delta": {},
|
| 700 |
+
"logprobs": null,
|
| 701 |
+
"finish_reason": null,
|
| 702 |
+
"token_ids": [
|
| 703 |
+
397
|
| 704 |
+
]
|
| 705 |
+
}
|
| 706 |
+
]
|
| 707 |
+
},
|
| 708 |
+
{
|
| 709 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 710 |
+
"object": "chat.completion.chunk",
|
| 711 |
+
"created": 1790592279,
|
| 712 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 713 |
+
"choices": [
|
| 714 |
+
{
|
| 715 |
+
"index": 0,
|
| 716 |
+
"delta": {},
|
| 717 |
+
"logprobs": null,
|
| 718 |
+
"finish_reason": null,
|
| 719 |
+
"token_ids": [
|
| 720 |
+
522
|
| 721 |
+
]
|
| 722 |
+
}
|
| 723 |
+
]
|
| 724 |
+
},
|
| 725 |
+
{
|
| 726 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 727 |
+
"object": "chat.completion.chunk",
|
| 728 |
+
"created": 1790592279,
|
| 729 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 730 |
+
"choices": [
|
| 731 |
+
{
|
| 732 |
+
"index": 0,
|
| 733 |
+
"delta": {},
|
| 734 |
+
"logprobs": null,
|
| 735 |
+
"finish_reason": null,
|
| 736 |
+
"token_ids": [
|
| 737 |
+
1688
|
| 738 |
+
]
|
| 739 |
+
}
|
| 740 |
+
]
|
| 741 |
+
},
|
| 742 |
+
{
|
| 743 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 744 |
+
"object": "chat.completion.chunk",
|
| 745 |
+
"created": 1790592279,
|
| 746 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 747 |
+
"choices": [
|
| 748 |
+
{
|
| 749 |
+
"index": 0,
|
| 750 |
+
"delta": {
|
| 751 |
+
"tool_calls": [
|
| 752 |
+
{
|
| 753 |
+
"index": 0,
|
| 754 |
+
"function": {
|
| 755 |
+
"arguments": "\"}"
|
| 756 |
+
}
|
| 757 |
+
}
|
| 758 |
+
]
|
| 759 |
+
},
|
| 760 |
+
"logprobs": null,
|
| 761 |
+
"finish_reason": null,
|
| 762 |
+
"token_ids": [
|
| 763 |
+
397
|
| 764 |
+
]
|
| 765 |
+
}
|
| 766 |
+
]
|
| 767 |
+
},
|
| 768 |
+
{
|
| 769 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 770 |
+
"object": "chat.completion.chunk",
|
| 771 |
+
"created": 1790592279,
|
| 772 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 773 |
+
"choices": [
|
| 774 |
+
{
|
| 775 |
+
"index": 0,
|
| 776 |
+
"delta": {},
|
| 777 |
+
"logprobs": null,
|
| 778 |
+
"finish_reason": null,
|
| 779 |
+
"token_ids": [
|
| 780 |
+
151658
|
| 781 |
+
]
|
| 782 |
+
}
|
| 783 |
+
]
|
| 784 |
+
},
|
| 785 |
+
{
|
| 786 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 787 |
+
"object": "chat.completion.chunk",
|
| 788 |
+
"created": 1790592279,
|
| 789 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 790 |
+
"choices": [
|
| 791 |
+
{
|
| 792 |
+
"index": 0,
|
| 793 |
+
"delta": {},
|
| 794 |
+
"logprobs": null,
|
| 795 |
+
"finish_reason": "tool_calls",
|
| 796 |
+
"stop_reason": null,
|
| 797 |
+
"token_ids": [
|
| 798 |
+
151645
|
| 799 |
+
]
|
| 800 |
+
}
|
| 801 |
+
]
|
| 802 |
+
},
|
| 803 |
+
{
|
| 804 |
+
"id": "chatcmpl-a08784d157aa41e3",
|
| 805 |
+
"object": "chat.completion.chunk",
|
| 806 |
+
"created": 1790592279,
|
| 807 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 808 |
+
"choices": [],
|
| 809 |
+
"usage": {
|
| 810 |
+
"prompt_tokens": 282,
|
| 811 |
+
"total_tokens": 305,
|
| 812 |
+
"completion_tokens": 23,
|
| 813 |
+
"completion_tokens_details": {
|
| 814 |
+
"reasoning_tokens": 0
|
| 815 |
+
}
|
| 816 |
+
},
|
| 817 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b"
|
| 818 |
+
}
|
| 819 |
+
]
|
| 820 |
+
},
|
| 821 |
+
"thinking": {
|
| 822 |
+
"request": {
|
| 823 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 824 |
+
"messages": [
|
| 825 |
+
{
|
| 826 |
+
"role": "user",
|
| 827 |
+
"content": "Calculate 6 times 7. Think briefly, then give the answer."
|
| 828 |
+
}
|
| 829 |
+
],
|
| 830 |
+
"temperature": 0,
|
| 831 |
+
"max_tokens": 256,
|
| 832 |
+
"stream": true,
|
| 833 |
+
"stream_options": {
|
| 834 |
+
"include_usage": true
|
| 835 |
+
},
|
| 836 |
+
"return_token_ids": true,
|
| 837 |
+
"chat_template_kwargs": {
|
| 838 |
+
"enable_thinking": true
|
| 839 |
+
},
|
| 840 |
+
"reasoning_effort": "low"
|
| 841 |
+
},
|
| 842 |
+
"content": "\n\n42",
|
| 843 |
+
"reasoning": "\nWe need answer simple. Need think briefly then answer. 6*7=42. Final concise.\n",
|
| 844 |
+
"tool_calls": {},
|
| 845 |
+
"usage": {
|
| 846 |
+
"prompt_tokens": 57,
|
| 847 |
+
"total_tokens": 86,
|
| 848 |
+
"completion_tokens": 29,
|
| 849 |
+
"completion_tokens_details": {
|
| 850 |
+
"reasoning_tokens": 23
|
| 851 |
+
}
|
| 852 |
+
},
|
| 853 |
+
"events": [
|
| 854 |
+
{
|
| 855 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 856 |
+
"object": "chat.completion.chunk",
|
| 857 |
+
"created": 1790592280,
|
| 858 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 859 |
+
"choices": [
|
| 860 |
+
{
|
| 861 |
+
"index": 0,
|
| 862 |
+
"delta": {
|
| 863 |
+
"role": "assistant",
|
| 864 |
+
"content": ""
|
| 865 |
+
},
|
| 866 |
+
"logprobs": null,
|
| 867 |
+
"finish_reason": null
|
| 868 |
+
}
|
| 869 |
+
],
|
| 870 |
+
"prompt_token_ids": [
|
| 871 |
+
151644,
|
| 872 |
+
8948,
|
| 873 |
+
198,
|
| 874 |
+
25139,
|
| 875 |
+
287,
|
| 876 |
+
30022,
|
| 877 |
+
371,
|
| 878 |
+
25,
|
| 879 |
+
12041,
|
| 880 |
+
151645,
|
| 881 |
+
151644,
|
| 882 |
+
8948,
|
| 883 |
+
198,
|
| 884 |
+
2610,
|
| 885 |
+
525,
|
| 886 |
+
12812,
|
| 887 |
+
533,
|
| 888 |
+
11250,
|
| 889 |
+
15,
|
| 890 |
+
13,
|
| 891 |
+
20,
|
| 892 |
+
12,
|
| 893 |
+
23876,
|
| 894 |
+
11,
|
| 895 |
+
264,
|
| 896 |
+
10950,
|
| 897 |
+
15235,
|
| 898 |
+
17847,
|
| 899 |
+
44936,
|
| 900 |
+
553,
|
| 901 |
+
12812,
|
| 902 |
+
533,
|
| 903 |
+
15235,
|
| 904 |
+
13,
|
| 905 |
+
151645,
|
| 906 |
+
151644,
|
| 907 |
+
872,
|
| 908 |
+
198,
|
| 909 |
+
47866,
|
| 910 |
+
220,
|
| 911 |
+
21,
|
| 912 |
+
3039,
|
| 913 |
+
220,
|
| 914 |
+
22,
|
| 915 |
+
13,
|
| 916 |
+
21149,
|
| 917 |
+
26753,
|
| 918 |
+
11,
|
| 919 |
+
1221,
|
| 920 |
+
2968,
|
| 921 |
+
279,
|
| 922 |
+
4226,
|
| 923 |
+
13,
|
| 924 |
+
151645,
|
| 925 |
+
151644,
|
| 926 |
+
77091,
|
| 927 |
+
198
|
| 928 |
+
],
|
| 929 |
+
"prompt_text": null
|
| 930 |
+
},
|
| 931 |
+
{
|
| 932 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 933 |
+
"object": "chat.completion.chunk",
|
| 934 |
+
"created": 1790592280,
|
| 935 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 936 |
+
"choices": [
|
| 937 |
+
{
|
| 938 |
+
"index": 0,
|
| 939 |
+
"delta": {},
|
| 940 |
+
"logprobs": null,
|
| 941 |
+
"finish_reason": null,
|
| 942 |
+
"token_ids": [
|
| 943 |
+
151667
|
| 944 |
+
]
|
| 945 |
+
}
|
| 946 |
+
]
|
| 947 |
+
},
|
| 948 |
+
{
|
| 949 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 950 |
+
"object": "chat.completion.chunk",
|
| 951 |
+
"created": 1790592280,
|
| 952 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 953 |
+
"choices": [
|
| 954 |
+
{
|
| 955 |
+
"index": 0,
|
| 956 |
+
"delta": {
|
| 957 |
+
"reasoning": "\n"
|
| 958 |
+
},
|
| 959 |
+
"logprobs": null,
|
| 960 |
+
"finish_reason": null,
|
| 961 |
+
"token_ids": [
|
| 962 |
+
198
|
| 963 |
+
]
|
| 964 |
+
}
|
| 965 |
+
]
|
| 966 |
+
},
|
| 967 |
+
{
|
| 968 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 969 |
+
"object": "chat.completion.chunk",
|
| 970 |
+
"created": 1790592280,
|
| 971 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 972 |
+
"choices": [
|
| 973 |
+
{
|
| 974 |
+
"index": 0,
|
| 975 |
+
"delta": {
|
| 976 |
+
"reasoning": "We"
|
| 977 |
+
},
|
| 978 |
+
"logprobs": null,
|
| 979 |
+
"finish_reason": null,
|
| 980 |
+
"token_ids": [
|
| 981 |
+
1654
|
| 982 |
+
]
|
| 983 |
+
}
|
| 984 |
+
]
|
| 985 |
+
},
|
| 986 |
+
{
|
| 987 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 988 |
+
"object": "chat.completion.chunk",
|
| 989 |
+
"created": 1790592280,
|
| 990 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 991 |
+
"choices": [
|
| 992 |
+
{
|
| 993 |
+
"index": 0,
|
| 994 |
+
"delta": {
|
| 995 |
+
"reasoning": " need"
|
| 996 |
+
},
|
| 997 |
+
"logprobs": null,
|
| 998 |
+
"finish_reason": null,
|
| 999 |
+
"token_ids": [
|
| 1000 |
+
1184
|
| 1001 |
+
]
|
| 1002 |
+
}
|
| 1003 |
+
]
|
| 1004 |
+
},
|
| 1005 |
+
{
|
| 1006 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1007 |
+
"object": "chat.completion.chunk",
|
| 1008 |
+
"created": 1790592280,
|
| 1009 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1010 |
+
"choices": [
|
| 1011 |
+
{
|
| 1012 |
+
"index": 0,
|
| 1013 |
+
"delta": {
|
| 1014 |
+
"reasoning": " answer"
|
| 1015 |
+
},
|
| 1016 |
+
"logprobs": null,
|
| 1017 |
+
"finish_reason": null,
|
| 1018 |
+
"token_ids": [
|
| 1019 |
+
4226
|
| 1020 |
+
]
|
| 1021 |
+
}
|
| 1022 |
+
]
|
| 1023 |
+
},
|
| 1024 |
+
{
|
| 1025 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1026 |
+
"object": "chat.completion.chunk",
|
| 1027 |
+
"created": 1790592280,
|
| 1028 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1029 |
+
"choices": [
|
| 1030 |
+
{
|
| 1031 |
+
"index": 0,
|
| 1032 |
+
"delta": {
|
| 1033 |
+
"reasoning": " simple"
|
| 1034 |
+
},
|
| 1035 |
+
"logprobs": null,
|
| 1036 |
+
"finish_reason": null,
|
| 1037 |
+
"token_ids": [
|
| 1038 |
+
4285
|
| 1039 |
+
]
|
| 1040 |
+
}
|
| 1041 |
+
]
|
| 1042 |
+
},
|
| 1043 |
+
{
|
| 1044 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1045 |
+
"object": "chat.completion.chunk",
|
| 1046 |
+
"created": 1790592280,
|
| 1047 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1048 |
+
"choices": [
|
| 1049 |
+
{
|
| 1050 |
+
"index": 0,
|
| 1051 |
+
"delta": {
|
| 1052 |
+
"reasoning": "."
|
| 1053 |
+
},
|
| 1054 |
+
"logprobs": null,
|
| 1055 |
+
"finish_reason": null,
|
| 1056 |
+
"token_ids": [
|
| 1057 |
+
13
|
| 1058 |
+
]
|
| 1059 |
+
}
|
| 1060 |
+
]
|
| 1061 |
+
},
|
| 1062 |
+
{
|
| 1063 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1064 |
+
"object": "chat.completion.chunk",
|
| 1065 |
+
"created": 1790592280,
|
| 1066 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1067 |
+
"choices": [
|
| 1068 |
+
{
|
| 1069 |
+
"index": 0,
|
| 1070 |
+
"delta": {
|
| 1071 |
+
"reasoning": " Need"
|
| 1072 |
+
},
|
| 1073 |
+
"logprobs": null,
|
| 1074 |
+
"finish_reason": null,
|
| 1075 |
+
"token_ids": [
|
| 1076 |
+
14656
|
| 1077 |
+
]
|
| 1078 |
+
}
|
| 1079 |
+
]
|
| 1080 |
+
},
|
| 1081 |
+
{
|
| 1082 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1083 |
+
"object": "chat.completion.chunk",
|
| 1084 |
+
"created": 1790592280,
|
| 1085 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1086 |
+
"choices": [
|
| 1087 |
+
{
|
| 1088 |
+
"index": 0,
|
| 1089 |
+
"delta": {
|
| 1090 |
+
"reasoning": " think"
|
| 1091 |
+
},
|
| 1092 |
+
"logprobs": null,
|
| 1093 |
+
"finish_reason": null,
|
| 1094 |
+
"token_ids": [
|
| 1095 |
+
1744
|
| 1096 |
+
]
|
| 1097 |
+
}
|
| 1098 |
+
]
|
| 1099 |
+
},
|
| 1100 |
+
{
|
| 1101 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1102 |
+
"object": "chat.completion.chunk",
|
| 1103 |
+
"created": 1790592280,
|
| 1104 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1105 |
+
"choices": [
|
| 1106 |
+
{
|
| 1107 |
+
"index": 0,
|
| 1108 |
+
"delta": {
|
| 1109 |
+
"reasoning": " briefly"
|
| 1110 |
+
},
|
| 1111 |
+
"logprobs": null,
|
| 1112 |
+
"finish_reason": null,
|
| 1113 |
+
"token_ids": [
|
| 1114 |
+
26753
|
| 1115 |
+
]
|
| 1116 |
+
}
|
| 1117 |
+
]
|
| 1118 |
+
},
|
| 1119 |
+
{
|
| 1120 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1121 |
+
"object": "chat.completion.chunk",
|
| 1122 |
+
"created": 1790592280,
|
| 1123 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1124 |
+
"choices": [
|
| 1125 |
+
{
|
| 1126 |
+
"index": 0,
|
| 1127 |
+
"delta": {
|
| 1128 |
+
"reasoning": " then"
|
| 1129 |
+
},
|
| 1130 |
+
"logprobs": null,
|
| 1131 |
+
"finish_reason": null,
|
| 1132 |
+
"token_ids": [
|
| 1133 |
+
1221
|
| 1134 |
+
]
|
| 1135 |
+
}
|
| 1136 |
+
]
|
| 1137 |
+
},
|
| 1138 |
+
{
|
| 1139 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1140 |
+
"object": "chat.completion.chunk",
|
| 1141 |
+
"created": 1790592280,
|
| 1142 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1143 |
+
"choices": [
|
| 1144 |
+
{
|
| 1145 |
+
"index": 0,
|
| 1146 |
+
"delta": {
|
| 1147 |
+
"reasoning": " answer"
|
| 1148 |
+
},
|
| 1149 |
+
"logprobs": null,
|
| 1150 |
+
"finish_reason": null,
|
| 1151 |
+
"token_ids": [
|
| 1152 |
+
4226
|
| 1153 |
+
]
|
| 1154 |
+
}
|
| 1155 |
+
]
|
| 1156 |
+
},
|
| 1157 |
+
{
|
| 1158 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1159 |
+
"object": "chat.completion.chunk",
|
| 1160 |
+
"created": 1790592280,
|
| 1161 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1162 |
+
"choices": [
|
| 1163 |
+
{
|
| 1164 |
+
"index": 0,
|
| 1165 |
+
"delta": {
|
| 1166 |
+
"reasoning": "."
|
| 1167 |
+
},
|
| 1168 |
+
"logprobs": null,
|
| 1169 |
+
"finish_reason": null,
|
| 1170 |
+
"token_ids": [
|
| 1171 |
+
13
|
| 1172 |
+
]
|
| 1173 |
+
}
|
| 1174 |
+
]
|
| 1175 |
+
},
|
| 1176 |
+
{
|
| 1177 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1178 |
+
"object": "chat.completion.chunk",
|
| 1179 |
+
"created": 1790592280,
|
| 1180 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1181 |
+
"choices": [
|
| 1182 |
+
{
|
| 1183 |
+
"index": 0,
|
| 1184 |
+
"delta": {
|
| 1185 |
+
"reasoning": " "
|
| 1186 |
+
},
|
| 1187 |
+
"logprobs": null,
|
| 1188 |
+
"finish_reason": null,
|
| 1189 |
+
"token_ids": [
|
| 1190 |
+
220
|
| 1191 |
+
]
|
| 1192 |
+
}
|
| 1193 |
+
]
|
| 1194 |
+
},
|
| 1195 |
+
{
|
| 1196 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1197 |
+
"object": "chat.completion.chunk",
|
| 1198 |
+
"created": 1790592280,
|
| 1199 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1200 |
+
"choices": [
|
| 1201 |
+
{
|
| 1202 |
+
"index": 0,
|
| 1203 |
+
"delta": {
|
| 1204 |
+
"reasoning": "6"
|
| 1205 |
+
},
|
| 1206 |
+
"logprobs": null,
|
| 1207 |
+
"finish_reason": null,
|
| 1208 |
+
"token_ids": [
|
| 1209 |
+
21
|
| 1210 |
+
]
|
| 1211 |
+
}
|
| 1212 |
+
]
|
| 1213 |
+
},
|
| 1214 |
+
{
|
| 1215 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1216 |
+
"object": "chat.completion.chunk",
|
| 1217 |
+
"created": 1790592280,
|
| 1218 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1219 |
+
"choices": [
|
| 1220 |
+
{
|
| 1221 |
+
"index": 0,
|
| 1222 |
+
"delta": {
|
| 1223 |
+
"reasoning": "*"
|
| 1224 |
+
},
|
| 1225 |
+
"logprobs": null,
|
| 1226 |
+
"finish_reason": null,
|
| 1227 |
+
"token_ids": [
|
| 1228 |
+
9
|
| 1229 |
+
]
|
| 1230 |
+
}
|
| 1231 |
+
]
|
| 1232 |
+
},
|
| 1233 |
+
{
|
| 1234 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1235 |
+
"object": "chat.completion.chunk",
|
| 1236 |
+
"created": 1790592280,
|
| 1237 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1238 |
+
"choices": [
|
| 1239 |
+
{
|
| 1240 |
+
"index": 0,
|
| 1241 |
+
"delta": {
|
| 1242 |
+
"reasoning": "7"
|
| 1243 |
+
},
|
| 1244 |
+
"logprobs": null,
|
| 1245 |
+
"finish_reason": null,
|
| 1246 |
+
"token_ids": [
|
| 1247 |
+
22
|
| 1248 |
+
]
|
| 1249 |
+
}
|
| 1250 |
+
]
|
| 1251 |
+
},
|
| 1252 |
+
{
|
| 1253 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1254 |
+
"object": "chat.completion.chunk",
|
| 1255 |
+
"created": 1790592280,
|
| 1256 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1257 |
+
"choices": [
|
| 1258 |
+
{
|
| 1259 |
+
"index": 0,
|
| 1260 |
+
"delta": {
|
| 1261 |
+
"reasoning": "="
|
| 1262 |
+
},
|
| 1263 |
+
"logprobs": null,
|
| 1264 |
+
"finish_reason": null,
|
| 1265 |
+
"token_ids": [
|
| 1266 |
+
28
|
| 1267 |
+
]
|
| 1268 |
+
}
|
| 1269 |
+
]
|
| 1270 |
+
},
|
| 1271 |
+
{
|
| 1272 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1273 |
+
"object": "chat.completion.chunk",
|
| 1274 |
+
"created": 1790592280,
|
| 1275 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1276 |
+
"choices": [
|
| 1277 |
+
{
|
| 1278 |
+
"index": 0,
|
| 1279 |
+
"delta": {
|
| 1280 |
+
"reasoning": "4"
|
| 1281 |
+
},
|
| 1282 |
+
"logprobs": null,
|
| 1283 |
+
"finish_reason": null,
|
| 1284 |
+
"token_ids": [
|
| 1285 |
+
19
|
| 1286 |
+
]
|
| 1287 |
+
}
|
| 1288 |
+
]
|
| 1289 |
+
},
|
| 1290 |
+
{
|
| 1291 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1292 |
+
"object": "chat.completion.chunk",
|
| 1293 |
+
"created": 1790592280,
|
| 1294 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1295 |
+
"choices": [
|
| 1296 |
+
{
|
| 1297 |
+
"index": 0,
|
| 1298 |
+
"delta": {
|
| 1299 |
+
"reasoning": "2"
|
| 1300 |
+
},
|
| 1301 |
+
"logprobs": null,
|
| 1302 |
+
"finish_reason": null,
|
| 1303 |
+
"token_ids": [
|
| 1304 |
+
17
|
| 1305 |
+
]
|
| 1306 |
+
}
|
| 1307 |
+
]
|
| 1308 |
+
},
|
| 1309 |
+
{
|
| 1310 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1311 |
+
"object": "chat.completion.chunk",
|
| 1312 |
+
"created": 1790592280,
|
| 1313 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1314 |
+
"choices": [
|
| 1315 |
+
{
|
| 1316 |
+
"index": 0,
|
| 1317 |
+
"delta": {
|
| 1318 |
+
"reasoning": "."
|
| 1319 |
+
},
|
| 1320 |
+
"logprobs": null,
|
| 1321 |
+
"finish_reason": null,
|
| 1322 |
+
"token_ids": [
|
| 1323 |
+
13
|
| 1324 |
+
]
|
| 1325 |
+
}
|
| 1326 |
+
]
|
| 1327 |
+
},
|
| 1328 |
+
{
|
| 1329 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1330 |
+
"object": "chat.completion.chunk",
|
| 1331 |
+
"created": 1790592280,
|
| 1332 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1333 |
+
"choices": [
|
| 1334 |
+
{
|
| 1335 |
+
"index": 0,
|
| 1336 |
+
"delta": {
|
| 1337 |
+
"reasoning": " Final"
|
| 1338 |
+
},
|
| 1339 |
+
"logprobs": null,
|
| 1340 |
+
"finish_reason": null,
|
| 1341 |
+
"token_ids": [
|
| 1342 |
+
13023
|
| 1343 |
+
]
|
| 1344 |
+
}
|
| 1345 |
+
]
|
| 1346 |
+
},
|
| 1347 |
+
{
|
| 1348 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1349 |
+
"object": "chat.completion.chunk",
|
| 1350 |
+
"created": 1790592280,
|
| 1351 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1352 |
+
"choices": [
|
| 1353 |
+
{
|
| 1354 |
+
"index": 0,
|
| 1355 |
+
"delta": {
|
| 1356 |
+
"reasoning": " concise"
|
| 1357 |
+
},
|
| 1358 |
+
"logprobs": null,
|
| 1359 |
+
"finish_reason": null,
|
| 1360 |
+
"token_ids": [
|
| 1361 |
+
63594
|
| 1362 |
+
]
|
| 1363 |
+
}
|
| 1364 |
+
]
|
| 1365 |
+
},
|
| 1366 |
+
{
|
| 1367 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1368 |
+
"object": "chat.completion.chunk",
|
| 1369 |
+
"created": 1790592280,
|
| 1370 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1371 |
+
"choices": [
|
| 1372 |
+
{
|
| 1373 |
+
"index": 0,
|
| 1374 |
+
"delta": {
|
| 1375 |
+
"reasoning": ".\n"
|
| 1376 |
+
},
|
| 1377 |
+
"logprobs": null,
|
| 1378 |
+
"finish_reason": null,
|
| 1379 |
+
"token_ids": [
|
| 1380 |
+
624
|
| 1381 |
+
]
|
| 1382 |
+
}
|
| 1383 |
+
]
|
| 1384 |
+
},
|
| 1385 |
+
{
|
| 1386 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1387 |
+
"object": "chat.completion.chunk",
|
| 1388 |
+
"created": 1790592280,
|
| 1389 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1390 |
+
"choices": [
|
| 1391 |
+
{
|
| 1392 |
+
"index": 0,
|
| 1393 |
+
"delta": {},
|
| 1394 |
+
"logprobs": null,
|
| 1395 |
+
"finish_reason": null,
|
| 1396 |
+
"token_ids": [
|
| 1397 |
+
151668
|
| 1398 |
+
]
|
| 1399 |
+
}
|
| 1400 |
+
]
|
| 1401 |
+
},
|
| 1402 |
+
{
|
| 1403 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1404 |
+
"object": "chat.completion.chunk",
|
| 1405 |
+
"created": 1790592280,
|
| 1406 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1407 |
+
"choices": [
|
| 1408 |
+
{
|
| 1409 |
+
"index": 0,
|
| 1410 |
+
"delta": {},
|
| 1411 |
+
"logprobs": null,
|
| 1412 |
+
"finish_reason": null,
|
| 1413 |
+
"token_ids": [
|
| 1414 |
+
271
|
| 1415 |
+
]
|
| 1416 |
+
}
|
| 1417 |
+
]
|
| 1418 |
+
},
|
| 1419 |
+
{
|
| 1420 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1421 |
+
"object": "chat.completion.chunk",
|
| 1422 |
+
"created": 1790592280,
|
| 1423 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1424 |
+
"choices": [
|
| 1425 |
+
{
|
| 1426 |
+
"index": 0,
|
| 1427 |
+
"delta": {
|
| 1428 |
+
"content": "\n\n4"
|
| 1429 |
+
},
|
| 1430 |
+
"logprobs": null,
|
| 1431 |
+
"finish_reason": null,
|
| 1432 |
+
"token_ids": [
|
| 1433 |
+
19
|
| 1434 |
+
]
|
| 1435 |
+
}
|
| 1436 |
+
]
|
| 1437 |
+
},
|
| 1438 |
+
{
|
| 1439 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1440 |
+
"object": "chat.completion.chunk",
|
| 1441 |
+
"created": 1790592280,
|
| 1442 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1443 |
+
"choices": [
|
| 1444 |
+
{
|
| 1445 |
+
"index": 0,
|
| 1446 |
+
"delta": {
|
| 1447 |
+
"content": "2"
|
| 1448 |
+
},
|
| 1449 |
+
"logprobs": null,
|
| 1450 |
+
"finish_reason": null,
|
| 1451 |
+
"token_ids": [
|
| 1452 |
+
17
|
| 1453 |
+
]
|
| 1454 |
+
}
|
| 1455 |
+
]
|
| 1456 |
+
},
|
| 1457 |
+
{
|
| 1458 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1459 |
+
"object": "chat.completion.chunk",
|
| 1460 |
+
"created": 1790592280,
|
| 1461 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1462 |
+
"choices": [
|
| 1463 |
+
{
|
| 1464 |
+
"index": 0,
|
| 1465 |
+
"delta": {},
|
| 1466 |
+
"logprobs": null,
|
| 1467 |
+
"finish_reason": "stop",
|
| 1468 |
+
"stop_reason": null,
|
| 1469 |
+
"token_ids": [
|
| 1470 |
+
151645
|
| 1471 |
+
]
|
| 1472 |
+
}
|
| 1473 |
+
]
|
| 1474 |
+
},
|
| 1475 |
+
{
|
| 1476 |
+
"id": "chatcmpl-a9f0496c02f6b857",
|
| 1477 |
+
"object": "chat.completion.chunk",
|
| 1478 |
+
"created": 1790592280,
|
| 1479 |
+
"model": "Naive-N0.5-Flash-NVFP4",
|
| 1480 |
+
"choices": [],
|
| 1481 |
+
"usage": {
|
| 1482 |
+
"prompt_tokens": 57,
|
| 1483 |
+
"total_tokens": 86,
|
| 1484 |
+
"completion_tokens": 29,
|
| 1485 |
+
"completion_tokens_details": {
|
| 1486 |
+
"reasoning_tokens": 23
|
| 1487 |
+
}
|
| 1488 |
+
},
|
| 1489 |
+
"system_fingerprint": "vllm-0.28.0-tp4-13be3b5b"
|
| 1490 |
+
}
|
| 1491 |
+
]
|
| 1492 |
+
}
|
| 1493 |
+
}
|
validation/portable-preflight.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"versions": {
|
| 4 |
+
"vllm": "0.28.0",
|
| 5 |
+
"torch": "2.13.0+cu130",
|
| 6 |
+
"transformers": "5.17.0",
|
| 7 |
+
"accelerate": "1.15.0",
|
| 8 |
+
"tokenizers": "0.23.2",
|
| 9 |
+
"huggingface-hub": "1.33.0",
|
| 10 |
+
"safetensors": "0.8.0",
|
| 11 |
+
"flashinfer-python": "0.7.0",
|
| 12 |
+
"nvidia-cutlass-dsl": "4.6.2",
|
| 13 |
+
"triton": "3.7.1"
|
| 14 |
+
},
|
| 15 |
+
"gpus": [
|
| 16 |
+
{
|
| 17 |
+
"index": 0,
|
| 18 |
+
"name": "NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition",
|
| 19 |
+
"memory_bytes": 101973491712
|
| 20 |
+
},
|
| 21 |
+
{
|
| 22 |
+
"index": 1,
|
| 23 |
+
"name": "NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition",
|
| 24 |
+
"memory_bytes": 101973491712
|
| 25 |
+
},
|
| 26 |
+
{
|
| 27 |
+
"index": 2,
|
| 28 |
+
"name": "NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition",
|
| 29 |
+
"memory_bytes": 101970345984
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"index": 3,
|
| 33 |
+
"name": "NVIDIA RTX PRO 6000 Blackwell Max-Q Workstation Edition",
|
| 34 |
+
"memory_bytes": 101973491712
|
| 35 |
+
}
|
| 36 |
+
],
|
| 37 |
+
"shards": 49,
|
| 38 |
+
"tensors": 144856
|
| 39 |
+
}
|
validation/preserved-weights-validation.json
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"tensors_checked": 472,
|
| 4 |
+
"restored_from_source": {
|
| 5 |
+
"model-layer-00047.safetensors": [
|
| 6 |
+
"model.layers.47.mlp.gate.weight"
|
| 7 |
+
]
|
| 8 |
+
},
|
| 9 |
+
"check": "Exact source dtype, shape and SHA-256 of tensor payload"
|
| 10 |
+
}
|
validation/runtime-source-validation.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"passed": true,
|
| 3 |
+
"scope": "Active native vLLM container module bytes match published source files",
|
| 4 |
+
"files": {
|
| 5 |
+
"vllm_naive/attention.py": "f3aa650b110495224338b211330f6dcb7598cbeff917e7b1dac77695234f187c",
|
| 6 |
+
"vllm_naive/__init__.py": "8a5fddf2b89a4c33b6774a3ed75004a73db990ee711b8411e8772d7f2786f679",
|
| 7 |
+
"vllm_naive/model.py": "f0d5769018f8487c267d0ee6c3ba4cbf138e47d65c35c0cc0a00a95dfb69d763",
|
| 8 |
+
"scripts/benchmark_stream.py": "dab13abe554c6c28f89268ee3a2cec2e6425f73aa91f18692318b76886704157",
|
| 9 |
+
"scripts/safe_device_transfer.py": "61e931597e59e72ded3525976181e7164933e72f4647423c00ad2be0a57940db",
|
| 10 |
+
"scripts/decode_kernels.py": "ea0e71f5c4fd678b5cdf423b62ad07d37bed7de5fdc2af9ee89f08856ee34d09",
|
| 11 |
+
"scripts/validate_api.py": "82e04b0d21e9956da18930e27d35c4fc45f1a4b071bd2a19c6f62271deb74c2d",
|
| 12 |
+
"scripts/nvfp4_runtime.py": "be6453ca83d8f9ec528b07f17e78a41bfdcd8859fa9ec2644b6136e7068e9a1a",
|
| 13 |
+
"scripts/fused_experts.py": "f77eceec0a969eb7ff99e5177bd9d4cda1bfa3f0668ed614c060d28883f46018",
|
| 14 |
+
"scripts/preflight.py": "43ac170da1d7cf614fb5f4d7f0ee70635d2d78bd638bfb3af2322baf91a08600",
|
| 15 |
+
"sitecustomize.py": "552485e6e5e03c72c1d8b76a43a1ede48f8283a5d1e5ab93761125ec4a2c492b"
|
| 16 |
+
}
|
| 17 |
+
}
|