Instructions to use Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", trust_remote_code=True) messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoProcessor, AutoModelForImageTextToText processor = AutoProcessor.from_pretrained("Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", trust_remote_code=True) model = AutoModelForImageTextToText.from_pretrained("Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", trust_remote_code=True, device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=40) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
- SGLang
How to use Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV with Docker Model Runner:
docker model run hf.co/Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
- LOMONOSOV ZENIT 27B «ALTAY» — INDEV
- LOMONOSOV ZENIT 27B «ALTAY» — INDEV
- Что изменилось в этой версии: 1.47 ГиБ видеопамяти, при замеренном паритете
- Что это
- На чём запускается
- Сколько ждать
- Скорость генерации
- Удержание контекста
- RazorAttention: 6.3 ГБ видеопамяти, и чем за них платят
- Запуск через transformers
- Профили запуска
- Чего в модели нет
- Известные особенности
- Лицензия
- Как помочь
- Что изменилось в этой версии: 1.47 ГиБ видеопамяти, при замеренном паритете
LOMONOSOV ZENIT 27B «ALTAY» — INDEV
What changed in this release: 1.47 GiB of VRAM, measured at parity
The MLP of layers 32–63 was requantised from NVFP4 to asymmetric 3-bit
(pack-quantized, group 32, step search), and the embedding table from 8-bit to
4-bit. Attention, the recurrent layers and vision are untouched.
| previous weights | these weights | |
|---|---|---|
| files on disk | 15.79 GiB | 14.32 GiB |
| engine's own figure at load | 14.86 GiB | 14.86 GiB |
| retrieval, 34,140 tokens, 48 needles | 43/48 | 43/48 |
| retrieval, 260,148 tokens, 144 needles | 95/144 | 95/144 |
Both lengths were measured on this machine, on the same corpora, with the previous weights re-measured the same day as the baseline. The long comparison is a paired exact McNemar test over the individual needles: 16 needles lost, 16 gained, p = 1.0000. The short one: 2 lost, 2 gained, p = 1.0000.
This is not "lossless". It is not distinguishable from the previous weights on this probe at these two lengths. The probe's resolution is measured: in any paired comparison 13–16 needles out of 48 change sides, so it cannot see small differences, and it says nothing about reasoning, code, or generation stability.
What has NOT been re-measured on these weights — the previous card carried six retrieval lengths and three prose-comprehension numbers; four retrieval lengths (101,140 · 201,140 · 263,140 · 401,140) and all three prose numbers were measured on the previous weights and are therefore not claimed here. They are being re-taken. The million-token row is running as this is written.
The million, measured on one machine, paired. These weights ran the full 1,006,160-token corpus to completion: 11/48 needles, 48 s to load, 1375 s to prefill. The previous weights, on the same machine, the same corpus, the same runtime and with more free memory (30,964 MiB against 30,902), failed to start at all — out of memory, 137 MiB short, after the engine reported 16.31 GiB of weights against 14.86 GiB here.
So the million row cannot be a comparison: there is no baseline to compare with, because the previous weights do not reach the questions on this card with a normal desktop. What is measured is stronger than a comparison — the previous weights cannot serve the million here and these can. The 18.8% figure the earlier card carried was taken on a rented card with a corpus twenty tokens shorter, and the same position plan has been seen to differ by up to four needles between machines, so 11/48 is reported on its own and is not held against it.
Where the saved memory goes: the million-token profile needs about 1.47 GiB less, which on a 32 GB card is the difference between requiring an almost empty desktop and tolerating a normal one.
A 26,895,998,464-parameter language model with a 1,010,000-token context,
built to run on one consumer graphics card. With the vision tower and the ALTAY
overlay the checkpoint holds 27,274,981,624 parameters in total
(receipts/PARAMETER_COUNT_RECEIPT.json).
As it's an indev version, we can not guarantee great performance or effectiveness, including that of multimodality, we will publish benchmarks upon a release, we will specificially avoid benchmaxxing in order not to mislead users and not to deliver something that won't translate to a real-world usage. So far it doesn't leave you plenty of headroom, but we will fix that
This is a work in progress, and the card says so wherever it matters. Every number below was measured on our own hardware and has a receipt. Nothing is estimated, extrapolated or rounded in our favour. Where something does not work, it is written down as plainly as the things that do.
Русская версия ниже. / Russian version below.
What it is
Hybrid architecture: 48 gated delta layers with a fixed-size recurrent state and 16 layers of full attention, GQA with 24 query heads over 4 KV heads, head dimension 256. ALTAY-72M-SKV overlay: 72 logical layers over 64 physical KV units. Weights are NVFP4 for text, FP8 for attention, FP8 for vision, INT8 for embeddings. The KV cache is three-bit TurboQuant, 12.5 KiB per token.
Languages: English, Russian, Ukrainian. Image input works and is measured — the
model describes a picture it is given (receipts_vision/).
Vision was broken until 2026-07-26, and it was broken silently. An image killed the engine:
cuFuncSetAttribute → CUDA_ERROR_INVALID_VALUEinsidehumming_gemm. The vision layers were quantised as integerpack-quantizedwith group size 16, and on Blackwell that group size is accepted by exactly one kernel —humming— which does not launch there. Marlin takes −1/32/64/128, Conch −1/128, Machete and CUTLASS want Hopper, AllSpark has no sm_120. The profiles carriedskip_mm_profiling, which hid the same crash at startup, so nothing complained until someone passed an actual image. Nobody had.Moving to group 128 was not possible either:
linear_fc2has an input width of 4304 = 16 × 269, and 269 is prime.Read that as "group 16", not as "humming". Measured 2026-07-27 on the same sm_120 card at group 128, the humming path builds and computes across every integer width it offers — 2, 3, 4, 5, 6, 7 and 8 bits — with output magnitudes doubling per bit as random codes require. What fails on Blackwell is the group size the vision tower happened to carry, not the kernel library.
Measured ladder, on a live card, one image, one question:
vision scheme shard result integer, group 16 (was shipped) 331 MB engine dies NVFP4, group 16 254 MiB runs, answers !!!!!FP8 per-channel (now shipped) 445 MiB correct description BF16, unquantised 879 MiB correct, more detailed NVFP4 is closed by measurement: 10.78% mean weight error, which the format simply has at four bits on this distribution — the scale computation was checked against the library's own reference and matches. The literature says the same thing about the activations we also quantised: RepQ-ViT (arXiv:2212.08254), ADFQ-ViT (2407.02763) and APHQ-ViT (2504.02508) all identify post-LayerNorm and post-GELU activations as where four-bit ViTs die. Four-bit vision is reachable, but through calibration, not round-to-nearest.
The million survives the change. Verified with no flags on an idle 5090: weights 14.86 GiB, KV cache 1,017,164 tokens, window 1,010,001 chosen, model answers.
The "model size" badge above says about 17B. Ignore it. Hugging Face counts the elements in each tensor as they are stored, and most weights here are packed several to an element. Counted properly — original width recovered per tensor from the shape of its scale table, which resolves every packed tensor with none left over:
| parameters | |
|---|---|
| four-bit packed | 24,054,511,616 |
| eight-bit packed | 1,504,074,752 |
| unpacked: FP8 attention, BF16 norms and biases | 1,716,395,256 |
| total | 27,274,981,624 |
| of that, the language model | 26,895,998,464 |
| vision tower | 371,380,976 |
| ALTAY overlay | 7,602,184 |
Embeddings are not tied (tie_word_embeddings: false), so embed_tokens and
lm_head are 1,271,398,400 each and counted separately; there is no double
count. Nothing is missing from the files: 2,509 tensors, matching
model.safetensors.index.json exactly, every shard's header verified against its
file length after a round trip through the Hub.
Corrected 2026-07-26. This paragraph used to derive the figure as "11.96 billion bytes holding 23.9 billion parameters, add 3.17 billion FP8" — which sums to 27.07 billion, not to the number it claimed to produce, and it counted every
U8tensor as four-bit when the embeddings are eight-bit and the vision tower is mixed. It also said 2,503 tensors. And the headline called 26,895,998,464 the size of a multimodal model, when that figure is precisely the count with the multimodal part left out. The number itself had no primary source anywhere in the repository — it is measured now (receipts/PARAMETER_COUNT_RECEIPT.json, reproduced bycount_parameters.py), and it turns out to be exactly the language model.
Built on Qwen3.6-27B by Alibaba, then requantised and given the ALTAY overlay and the extended window. Development followed the practices of ChatGPT 5.6 Sol Max and Kimi K3, the latter shaping how it approaches front-end work. We name all three because provenance belongs in the card, not in a footnote somebody has to dig for.
Corrected 2026-07-26: the million window did not start out of the box, and every measurement of it was made with an override the model does not ship.
The
raw_1010kprofile declared a window of 1,010,001 tokens while the model declared a capacity of 1,010,000. One token apart, and vLLM refuses to start:ValidationError: User-specified max_model_len (1010001) is greater than the derived max_model_len. Anyone typingvllm serve <model>on a 5090 got that instead of the flagship window.It never surfaced because all five of our probes set
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1themselves and the shipped runtime sets it nowhere. The certificate and the whole retention curve were measured in a configuration a user does not have. Our no-flags check missed it too: that probe constrains memory, so selection always landed on 262,144 or 393,216 — windows below the declared capacity, where the validation never fires. The instrument built to find launch defects could not, by construction, find this one.Fixed and measured: the declared capacity is now 1,010,001, and the cache arena went from 13.15 to 13.00 GB — it was oversized against a window that needs 12.03 GiB. With no flags, no environment variable and nothing else on the card, the engine selects 1,010,001, reserves a 1,017,164-token cache and answers.
This paragraph used to say the busy-card case could not be fixed. That was wrong, and it is fixed — corrected 2026-07-26. It claimed: "No threshold can separate them; we tried two and measured both failing." A threshold separates them exactly. What was missing was not a threshold but a measurement of what the selector actually sees, and we had never taken it.
Three things were wrong at once. The engine died needing 80 MiB while 377 MiB sat reserved and unallocated — the card had the memory, the allocator had it fragmented. The cache arena carried 130 MiB of slack it did not need. And the profile's declared requirement was 168 MB too optimistic, so the million was being chosen on cards that could not run it.
All three are fixed: the profile now asks for expandable allocator segments (published before the first CUDA allocation, and never over a value you set), the arena is 13.00 GB, and
requires_free_bytesis the last budget at which the million was measured to start and answer. Measured across a ladder of nine memory levels: below roughly 640 MiB held by other processes the million is selected and runs; above it the engine steps down to 393,216 and runs. There is no longer a level at which it is selected and fails.What this does not do is make the million work on a busy card. It makes the refusal honest. If something is holding more than about 0.64 GiB you will get 393,216 tokens, not a crash — and if you want the million anyway, free the card.
Every receipt this card names by filename ships with the model, in
receipts/. Each one records the question it was answering, the
host, and what it did not establish. Where two receipts disagree — and one pair
does — the folder's index says which one the card uses and why.
What it runs on
| card | memory | context | source |
|---|---|---|---|
| RTX 5090 | 32 GB | 1,010,000 | measured |
| RTX 4090 | 24 GB | ~365,000, and only with explicit flags | measured, ADA_SM89_RECEIPT |
| RTX 6000 Ada / PRO 6000 | 48 GB | not tested | we have no such card; the profile ladder would pick the widest that fits |
| RTX 3090, A6000, A100 | — | will not load | vLLM's FP8 scheme needs compute capability 8.9 |
The 4090 story, corrected 2026-07-26. This row said 393,216 tokens, chosen automatically. That was wrong in the place it hurts most, because choosing automatically is the convenience this card sells.
With explicit flags a real 4090 works:
--max-model-lenand utilisation 0.92 give a KV arena holding 365,524 tokens and prefill at 790.7 tok/s (ADA_SM89_RECEIPT).With no flags it does not start. We could not rent an Ada card again, so this was measured by holding ballast on a 5090 until free memory matched a 4090's, then giving the bare command. The
long_393kprofile is selected and the engine dies of an out-of-memory error inside the FP4 autotuner. Forcinglong_262kinstead fails earlier, with a different error.A ladder brackets the threshold to 199 MB:
long_393kneeds about 25.5e9 bytes free at selection. It declares 24.05e9 — low by roughly 1.4 GB. A 4090 has 25.76e9 in total, so after the driver reserve and one CUDA context it has roughly 25.0–25.2e9 free, a few hundred megabytes under the line.Three separate causes, all diagnosed:
requires_free_byteswas estimated rather than measured and was low by about 1.5 GB on both affected profiles; pinningkv_cache_memory_bytesmakes vLLM skip memory profiling entirely, so the utilisation clamp that fires on a short card changes nothing; andlong_262kcarried nogpu_memory_utilizationat all, so the clamp could not act on it and vLLM's 0.92 default asked for more than the card has.Fixed, and the fix is measured. Thresholds were found with a ballast ladder and the selection is verified end to end at four memory levels — see the profile table below. A 24 GB card now selects 262,144 tokens with no flags and runs. The row above still says "explicit flags" because the window figure there, ~365,000, comes from a real Ada card and has not been re-measured since; the no-flags path itself is fixed.
The window is chosen by the model, from the memory actually free on your card. If the declared million does not fit, the widest profile that does is selected and one line explaining the substitution goes to the log.
On a 32 GB card that works and is measured, both headless and with a desktop
session. At 24 GB it works too, and that sentence replaces an earlier one saying
it did not: the profile requirements were re-measured, and the bare command now
selects 262,144 tokens and answers. Re-confirmed on the release configuration
2026-07-26 (ada_expandable.json, ada_control.json) — by ballast on a 5090,
not on Ada silicon, the same instrument that found the defect.
About the million on a 5090, honestly. Weights take 14.86 GiB — that is the engine's own figure at load, not the size of the files, which is 14.32 GiB — and the cache arena 12.11 GiB, together 26.97 GiB. The measured peak of the whole process on a million-token run is about 30.0 GiB against the card's 31.84; the rest goes to activations and working buffers. That leaves roughly 1.8 GiB for the desktop. Measured bluntly: three runs in a row failed out of memory while a browser and other applications held about 1.6 GiB, and it went through once they were closed. On the previous weights the threshold was harder — the million needed about 1.47 GiB more and would not start under almost any desktop. A normal graphical session no longer blocks it, but the margin is small: a heavy browser or a second application on the card will still break the launch, and the model will step down to a shorter window on its own, which is the designed behaviour.
Installing
pip install vllm==0.25.1
pip install https://huggingface.co/Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV/resolve/main/lomonosov_zenit_altay_runtime-1.5.0-py3-none-any.whl
vllm serve Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
The middle line is not optional, and it is new here as of 2026-07-26. Without
it vllm serve refuses to start, with
Model architectures ['LomonosovZenitAltayForConditionalGeneration'] are not supported. The ALTAY architecture, the serving profiles, the TurboQuant KV codec
and the position map all live in that 88 KB package; vLLM has no way to install it
from a model repository on its own. Measured both ways: hidden, the engine refuses
at config time; installed from the wheel alone, the architecture resolves and the
profile applies. The wheel carries code only — no weights.
If you already have the model directory on disk, pip install <model directory>
does the same thing.
No patched vLLM is needed. The TurboQuant backend ships in the public wheel; six
files matched by sha256 across two independent installs (STOCK_VLLM_BACKEND_RECEIPT).
Transformers loads this model; it cannot compute it on a consumer card. Corrected 2026-07-27 — the paragraph that stood here said the config carried no
auto_mapand that loading fell back to stockqwen3_5. Both were true when written and are false now.Loading works and is measured:
AutoModelForImageTextToText.from_pretrainedwithtrust_remote_code=TruebuildsLomonosovZenitAltayForConditionalGeneration, the ALTAY overlay is present, the packed embeddings are materialised, nothing is left on meta — 12.7 s, 18.2 GB (receipts_transformers/). The multimodal class is not a detail:AutoModelForCausalLMbuilds a text tree undermodel.*while the weights live undermodel.language_model.*, and zero of 853 keys match.The forward pass is what does not fit. compressed-tensors ships no quantized kernels for transformers, so the first forward decompresses the whole model to bf16 — its own source says so (
model_compressor.py: "This allows for generation without requiring CT to handle quantized kernels"). That is about 55 GB. Offloading does not rescue it: accelerate places the packed weights first and decompression happens in place, on the device the layer already sits on.So both numbers are true and must not be conflated: through vLLM the model occupies 17–18 GB and runs on one consumer card; through transformers it loads at 18 GB and computes only on a machine with 64 GB or more.
library_namestaysvllmfor that reason — the Hub's "Use this model" snippet would otherwise send a 32 GB card into a 55 GB wall.
On a warm machine the engine is ready in about 53 seconds — median over 86 recorded starts, the middle of the range being roughly 49 to 77 seconds. Of that, reading the weights is 4.4 seconds: 14.86 GiB at about 3.7 GB/s, which is already NVMe speed and leaves nothing worth optimising. We checked, because a faster weight loader was on the list; the measurement retired the idea. The rest is engine initialisation.
The first run on a new machine takes 4 minutes longer while vLLM builds the
FP4 kernels for your card: 18 translation units, producing
fp4_gemm_cutlass_sm120.so at 5.4 MB. Measured on an RTX 5090. It is paid once
per machine and per FlashInfer version, then read from ~/.cache/flashinfer.
End to end, that is what you will actually wait. Measured 2026-07-27 on a second RTX 5090, clean install, nothing but the model path passed, weights on an NTFS volume mounted through FUSE:
| engine ready | first answer | |
|---|---|---|
| first start ever | 396 s | 27.3 s |
| every start after | 49 s | 16.4 s |
So the once-per-machine penalty is about five and a half minutes, of which the kernel build is the larger part and the first cold read of sixteen gigabytes of weights is the rest. The four minutes above is the build alone; this pair is what the clock in front of you shows.
The model limits that build's parallelism by available system memory. Left alone,
the compiler launches one job per core, each wants about 6 GB, and on a machine
with ordinary RAM the OOM killer takes it — which surfaces as
Engine core initialization failed, with the real cause (code=137) several
hundred lines further up and pointing at nothing. The guard picks
clamp(1, min(cores, available / 6 GB), 8) and logs one line saying why. It
never touches a MAX_JOBS you set yourself (FIRST_RUN_JIT_RECEIPT).
How long you will wait
The thing to know before you start: long context is read in minutes. RTX 5090
at stock clocks, turboquant_3bit_nc, one sequence.
| context | read time | tokens/s |
|---|---|---|
| 131,072 | 34 s | 3840 |
| 262,144 | 109 s | 2400 |
| 524,288 | 381 s (6.4 min) | 1375 |
| 1,010,000 | 22 min | 768 |
RTX 4090: 32,768 tokens in 38 s (861 tok/s).
Re-measured 2026-07-26, and the old row was slower than the model. This table used to read 2496 / 1799 / 1140 / 648. Those numbers had no receipt in this repository — an audit of every figure in the card went looking and found none — and they were taken before the arena, the position map and the allocator settings changed. Re-measured on the release configuration with
max_tokens=1, the model is 18–54% faster than the card claimed (receipts/prefill_table.json, reproduced byprefill_table.py).One measurement trap worth passing on: the first request in a fresh process compiles Triton kernels while it runs. Measured cold, 131,072 tokens gives 2277 tok/s; measured after one warm-up request, 3840 — the same work, 41% apart. The table above is the warm figure, which is what a running server delivers. The first request a user makes will be the slow one.
The slowdown with length is attention's quadratic cost rather than an implementation flaw: 381 s at 524,288 is faster than a pure quadratic extrapolation from 262,144.
The second question about the same text is nearly free. Prefix caching gives 16.9× / 52.9× / 172.9× were the figures published here.
Do not expect that at a million — corrected 2026-07-26. Two things were wrong. Those speedups have no surviving receipt in this repository; an audit of every number in the card went looking and found none. And prefix caching is switched off in the
raw_1010kprofile, so on the shipped default the second question at a million costs another full read, not 7.5 s.Switching it on does not fix that, it makes things worse, and now we know why. With prefix caching enabled the usable KV arena drops to 1,010,001 tokens — 489 blocks where the window needs 490. The cache can no longer hold the window it was sized for, and the engine stops: measured, 53 minutes at 0% GPU utilisation before we killed it. This is the same "arena tighter than the window" failure documented above, taken to its conclusion.
Below the million, where the arena has room, prefix caching can be switched on with
--enable-prefix-cachingand the second question is genuinely cheap — but we have not re-measured by how much, so no number is offered here.
Generation speed
About 150 ms per token, roughly 6–7 tokens per second, almost independent of context length (8K: 154 ms, 131K: 169 ms). That is slow and we know why: one step launches 4,192 GPU kernels for 44 ms of actual work, so the card spends most of the step waiting on the host. The three-bit KV codec accounts for 36% of the step; on fp8 a step takes 107 ms.
We are not dressing this up as optimal. The model earns its place where you need to read a lot, not where you need to talk fast.
CUDA graphs are off deliberately: measured 282 ms with them against 180 without. The per-step profile argues with that result, and re-checking it is on the list.
Context retention
Measured on the previous weights (NVFP4 everywhere, 15.79 GiB). These weights are not those; only 34,140 and 260,148 have been re-taken so far, see "What changed in this release" above. The rest is being re-measured.
Measured on real Russian prose with two independent instruments. Both were verified on short context before being pointed at long context.
Needles. Fourteen records of the form "Special note number 7: the archive access code is AMBER-6421" are planted at known depths and then asked about. The answer appears nowhere else in the text, so guessing is impossible.
Prose reading. Questions are built mechanically from the book's own text with one rare word blanked. Each question is first asked without the book, and anything the model answers from its memory of the classics is struck from the score.
This table was re-taken from scratch on 2026-07-26 with a 48-needle corpus.
The previous edition used fourteen needles, and we measured that a single
fourteen-needle run is worth ±14 points: two runs with nothing changed between
them returned 9/14 and 7/14. Those numbers are gone, not adjusted — a different
instrument is not a correction of the same figure. Method:
PROBE_NONDETERMINISM_FINDING.md.
| context | needles found | runs | first half | second half | previous plan |
|---|---|---|---|---|---|
| 34,140 | 42/48 = 87.5% | 3, identical | 66/72 | 60/72 | 87.5% (plan inactive) |
| 101,140 | 44/48 = 91.7% | 1 | 22/24 | 22/24 | 79.2% |
| 201,140 | 42/48 = 87.5% | 1 | 20/24 | 22/24 | 66.7% |
| 263,140 | 33/48 = 68.8% | 3, identical | 51/72 | 48/72 | 60.4% |
| 401,140 | 37/48 = 77.1% | 2, identical | 34/48 | 40/48 | 58.3% |
| 1,006,140 | 9/48 = 18.8% | 1 | 8/24 | 1/24 | 2.1% |
Rented RTX 5090, three-bit KV, the shipped position plan. Where a row was run three times the count came out identical every time. Rows run once are marked once. Between different machines the same plan can differ by up to four needles, so the host is named on purpose.
How exact that repetition is — corrected 2026-07-27. This section used to say the probe "reproduces exactly", which was a stronger claim than we could support. Repeats taken back to back do agree needle for needle; repeats separated by hours, with the machine touched in between, need not. One configuration at 260,140 tokens scored 33/48 in the afternoon and 35/48 three times in a row that night, same plan, same arena, same corpus checksum. Paired needle by needle the later runs are a strict superset: nothing was lost, two needles were gained. So read the table as exact within a sitting and good to a couple of needles across sittings.
What the table cannot resolve. Comparing two rows, or two settings, needle by needle shows that 13 to 16 needles out of 48 change sides in every such comparison — each setting genuinely helps some needles and hurts others. A difference of a dozen needles is real; a difference of five is not distinguishable with 48 needles, whatever the percentages suggest. Do not read small gaps in this table as findings.
That the position plan does real work is measured separately, and it is not small. On a denser corpus of the same length — 144 planted records in 260,148 tokens, three times the competing facts — untouched RoPE positions score 57/144 and the shipped plan scores 90/144. Paired: 12 needles lost, 45 gained, p below 0.0001. The same comparison on the 48-needle corpus returned p = 0.12, which is the resolution limit above, not an absence of effect.
The rightmost column is the plan this model shipped with until 2026-07-26. The position plans were replaced that day, per profile, and the gain is four to ten needles wherever the plan is active. Both columns are the same corpus, the same machine, the same probe; only the position plan differs.
Three things this table says.
Retention does not fall with length the way the old curve suggested. At 201,140 tokens the model now holds 87.5% — the same as at 34,140. The earlier decline from 87.5% to 66.7% across that span looked like a property of the model; most of it was a property of the position plan, whose stages started at 196,608 and so did nothing over most of that range. The new plan for that window compresses the middle frequency band from 65,536 onward.
The million is still not a retrieval window, even at nine times the old score. Nine needles out of forty-eight. Treat the million as a prefill and throughput capability — the model does ingest 1,006,140 tokens and answer — but do not expect it to find a fact you planted in the middle. The plan that reaches 18.8% divides positions by sixteen beyond 212,000, which is why its second half is nearly empty: sixteen adjacent tokens share one position out there, and nothing distinguishes them.
The dip at 263,140 is real, and it is an edge effect rather than a measurement
artefact. That corpus runs about a thousand tokens past the 262,144 window of the
long_262k profile, so we re-measured inside the window on a 260,140-token corpus:
33/48, identical. Crossing the boundary costs nothing; approaching it does. The
pairs the band does not cover keep native positions, and their share of the trained
range is what tracks the score — 101,140 uses 38.6% of it and reads 91.7%, 201,140
uses 76.7% and reads 87.5%, 260,140 uses 99.2% and reads 68.8%. Retention falls as
the prompt fills the trained window, before it leaves it.
Needle density is not constant across rows: the corpus holds 48 needles at every length, so it is 140.6 facts per 100K tokens at 34,140 and 12.0 at 401,140. Length and density move together in this table by construction.
Everything from here to the end of this section is development history, measured on the retired fourteen-needle instrument. Those runs are what led to the position plans this model ships, and the reasoning is kept because it is how the plans were found. None of the percentages below are current performance claims — for those, read the forty-eight-needle table above. A single fourteen-needle run is worth ±14 points, which is why the instrument was replaced.
The middle of this curve moved on 2026-07-26, and it moved a long way. The 250,000 row said 78.6%, and the staged position map took it to 92.9% on that instrument. Retrieval looked flat from thirty-three thousand tokens to a quarter of a million. On the forty-eight-needle corpus the same length reads 68.8%, and the flatness is not there — the two instruments disagree, and the denser one is the one we now publish.
What changed is one line of the position plan. The frequency pairs that complete between one and thirty-two turns over the trained window — pairs 15 to 21 of 32 — now have their positions halved above 196,608, while the other twenty-five keep true positions until 262,144. On the same host and the same corpus, the old map scores 10/14 and the new one 13/14, gaining three records and losing none.
Three things about that are worth your scepticism, and we share all three.
The gain was found by trying six prefixes and reporting the best, which is a selection effect — so it was re-tested on a different corpus that played no part in choosing it, and there it gained three again.
A gain of three needles is only slightly above the ±2 spread measured above, so a single observation of it would prove little. What carries it is that the same +3 appeared twice, on two corpora, one of which took no part in choosing the map. Two independent repeats of the same size are much harder to get from noise than one. We state the reasoning rather than the conclusion because the margin is thin.
The mechanism is not understood. Compressing a stretch of context containing no records at all still changes which records are found, so this is not "we fixed the angles for the needles". Four of the fourteen records sit near a decision boundary and any perturbation moves them; this one has moved them the same way twice, on two corpora.
And this is not the published method it resembles. The search was inspired by DPE (arXiv:2504.18857), which prescribes ranking dimensions by their measured 2-norm contribution to attention and remapping the top half. We measured that ranking — 16 attention layers, real activations, with a check that the per-pair split reproduces the whole rotary norm on every layer. It is nearly flat, 1.4% to 7.0% across 32 pairs, it has no relation to turn count, and the pairs we compress sit 32nd, 31st, 27th and 20th in it. Selecting by the paper's criterion instead scores 11/14 against our 13/14. So the band we ship is an empirical find named after the paper that prompted the search, not an application of it.
A million is unchanged at 2/14. The map costs nothing there and gains nothing; past the trained window the limit appears to be architectural.
Do not read 92.9% as "understands a quarter of a million tokens". The two instruments disagree, and the disagreement is the honest headline. On the same corpus, the same length and the same shipped configuration, prose comprehension scores 2 of 12. Without the map it scores 1 of 12, so the map helps there too — by one question, which at this denominator is barely a signal.
Finding a planted string and answering a question about the book are different tasks, and this model has become much better at the first while staying poor at the second. If your work is retrieval — pull the clause, find the record, locate the reference — the 92.9% is the number that matters. If your work is reasoning across a quarter of a million tokens of prose, the 16.7% is.
Correction, 2026-07-26. This row said 21.4% (3/14) until today. That number
was measured on the runtime before 1.5.0. On the runtime that ships, the same
configuration scores 2 of 14, and it is not a close call: six independent
runs — five repeats of the shipped map and one of plain division by four — all
returned 2/14 with byte-identical answers. Two receipts carry the same label
faithful262k_g4_1m across that runtime change, one scoring 3/14 and one 2/14.
The published figure is now the one the shipped artefact reproduces.
Length alone does not predict accuracy. It also depends on how many similar records the text contains. This is a different corpus family from the table above — denser plantings — so read the columns against each other, not against the curve above:
| length ↓ / records → | 4 | 8 | 14 | 40 |
|---|---|---|---|---|
| 33,000 | 78.6% | 82.5% | ||
| 250,000 | 100% | 75% | 64.3% | 60.0% |
| 1,005,000 | 25% | 14.3% |
At a quarter of a million, thinning the field helps enormously: four records are all found. At a million it stops helping. The million row was taken before runtime 1.5.0 except for the 14-record cell, which has been re-measured.
A model that was claimed to fit, and does not. An earlier version of this card said that if the target wins only when its logit beats every one of the other N−1 positions — probability Φ(Δ/σ)^(N−1) — then a single fitted margin-to-noise ratio of 4.666 reproduces all three measured points. It appeared to, but only because the three points it was fitted to came from three different places: 92.9% from one corpus, 64.3% from the denser corpus above, and 21.4% from the older runtime. Fitted to any set of three points that actually belong together, the one-parameter model misses badly:
| triple | best Δ/σ | largest miss |
|---|---|---|
| curve before the staged map, 92.9 / 78.6 / 14.3 | 4.670 | 10.0 points (250,000 under-predicted) |
| dense corpus, 78.6 / 64.3 / 14.3 | 4.576 | 13.9 points (33,000 over-predicted) |
So interference between similar records is a real effect and it explains the horizontal axis — thinning the field from fourteen records to four takes 250,000 from 64.3% to 100%. It does not explain the vertical axis. Something beyond crowding governs what happens as length grows, which is consistent with the rest of this card: past the trained window the limit is the fixed-size state of the forty-eight gated layers, and no amount of thinning the distractors changes that.
What this means for you. The model reads a million tokens in full, with nothing dropped and nothing summarised, and that is confirmed end to end. But do not count on it finding a particular line near the start of a million-token document. Reliable retrieval runs to about a quarter of a million tokens, and it is more reliable the fewer near-identical records the text holds: at 250,000 that is 64% with fourteen competing records and 100% with four. Beyond that it still reads, but finds poorly — around a fifth at a million regardless of how many facts are present, with the hits clustering in the last 150,000 tokens.
The three-bit cache costs you nothing in accuracy
A fair suspicion: context is stored at three bits per value, so are we paying for that in retrieval quality? Tested directly — one corpus, one length of 250,000, one position map, only the storage format differs:
| KV | bytes/token | found |
|---|---|---|
| three-bit TurboQuant (shipped) | 12,785 | 24/40 |
| fp8, essentially noise-free | 32,768 | 28/40 |
Ten points apart, but the arms ran on the same needles, so the correct test is paired: ten discordant pairs, seven against three, exact McNemar p = 0.34. Not significant. More telling than the p-value: twenty-one needles were found by both arms and nine by neither, even with a noise-free cache. Those nine are lost to competition among similar records, not to storage noise.
Why the checkpoint does not use YaRN
The model is trained on 262,144 positions. The declared million is a training-free extension: 262,144 × 3.85284 = 1,010,000 exactly.
An intermediate build shipped YaRN with that factor, and it cost accuracy inside the trained window. Measured on one corpus, one truncation, with the position map as the only difference:
| at 250,000 tokens | needles | accuracy |
|---|---|---|
| YaRN as shipped | 9/14 | 64.3% |
| YaRN with attention_factor = 1 | 10/14 | 71.4% |
| native positions | 11/14 | 78.6% |
YaRN does two things and each cost about one needle. It multiplies attention
logits by 1.288 unconditionally at every input length, including short ones
the model was trained on. And it compresses the ten slowest frequency pairs of
thirty-two, when at rope_theta = 1e7 the slowest pair does not complete three
per cent of a turn across the whole million, so there is nothing there to
compress.
So the release ships native positions, and windows wider than the trained one get their positions another way — see below.
Serving profiles
The model carries its launch parameters in its own config.json. Selection
order:
- the
ZENIT_SERVING_PROFILEvariable; - an explicit
--max-model-len, which takes the smallest profile that holds it; - otherwise the widest profile that fits the memory actually free, probed through NVML without creating a CUDA context;
- otherwise the default profile.
Anything you pass on the command line always beats the profile, and every substitution is logged.
| profile | window | free memory required | measured |
|---|---|---|---|
raw_1010k |
1,010,001 | 32.34 GB | threshold measured to 27 MB |
long_393k |
393,216 | 25.57 GB | threshold measured to 199 MB |
long_262k |
262,144 | 23.97 GB | threshold measured to 510 MB |
All three requirements are measured, not estimated, and that is a change. Until 2026-07-26 they were estimates, and both were low by about 1.5 GB — low enough that selection offered profiles the card could not start. A ballast ladder on a rented 5090 found the real thresholds by holding memory at successive levels and giving the bare command each time.
The whole selection is now verified end to end at four memory levels: 26.57 GB free selects the 393,216 window and runs; 25.67 and 24.47 select 262,144 and run; 23.17 fits no profile at all, and the log says so by name and number before it stops. That last case is correct rather than broken — the weights alone are 14.86 GiB, and a card with 21 GiB free cannot run this model at any window.
long_262k also carries an explicit gpu_memory_utilization now. Without it the
clamp had nothing to lower and vLLM's 0.92 default asked for more than a short card
has. Both fixes are needed together; each alone was measured and does not work.
raw_1010k's requirement is now measured too, and the paragraph that used to
stand here was wrong twice over — corrected 2026-07-26. It said: "The
instrument cannot measure this profile; it consumes the very headroom under
test." It can. It also gave the untested band as 304 MB, which was itself a
product of the same mistake — the probe was reading free memory through
torch.cuda.mem_get_info(), and that call creates a CUDA context of about
498 MiB inside the probe's own process. Reading the driver through nvidia-smi
instead costs nothing, and the measurement becomes ordinary.
Measured that way, the declared value was low by 168 MB, and the consequence was the one that matters: the million was being offered on cards that could not start it. The figure now shipped, 32.34 GB, is the last budget at which the million was measured to start and answer; 27 MB below it, the engine comes up and then dies on the first request.
The lesson is not about this profile. Every "we cannot measure that" in this card deserves the same suspicion — twice now the obstacle has turned out to be the instrument rather than the thing.
Every profile carries a position plan, and since 2026-07-26 it has two stages: pairs 15 to 21 of the 32 frequency pairs divide their positions by two above 196,608, and every pair divides by four above 262,144.
This is no longer the identity inside the trained window, and that is the point. The earlier plan was — it left everything below 262,144 untouched — and that is precisely why six attempts to improve retrieval never moved 250,000: they all differed only above a mark the test never reached. The first stage reaches inside, and it is what took 250,334 tokens from 10/14 to 13/14.
Below 196,608 the map is still the identity, so short requests are untouched; measured, not asserted — the 33,334 arm returns answers byte-identical to a run with no plan at all.
The second stage was chosen at a million, and none of it helped there. At 1,005,334 tokens, fourteen needles, one machine, only the map differing: YaRN 0/14, division by 4 over all pairs 3/14, over slow pairs only 2/14, by 8 → 2/14, by 16 → 1/14, freezing the slow pairs at the window edge 0/14, and the map we ship 2/14. The staged map measures 2/14 there as well — it costs nothing at a million and gains nothing.
The first stage, the one that matters, was chosen at 262,334 and validated at 250,334 on a corpus that played no part in choosing it. That is the search described under retrieval above.
An earlier version of this card called everything between 1 and 3 of those indistinguishable, on the grounds that the instrument wobbles by about two needles. That figure was wrong. It came from comparing two different machines, so it contained the difference between the machines and not the noise of the measurement. Measured properly — one machine, one corpus, greedy decoding, only the KV arena varying across a 2.2× range — the spread is zero: all fourteen answers came back byte-identical in all four runs.
So the differences above are not dismissible as noise. The one that mattered — plain division scoring 3/14 against the shipped map's 2/14 — has since been run again, and it does not reproduce. On the runtime that ships, with the two arms differing in exactly one environment variable and agreeing on corpus, codec and length, both score 2/14. The sweep above was taken on an earlier runtime; that one-needle gap belongs to the runtime change, not to the map.
Equal scores, but not equal answers, and the distinction matters. Of fourteen answers only one is the same. The two maps even find different needles: the shipped map recovers records 12 and 13, plain division recovers 11 and 12. For comparison, repeating a single configuration five times gives fourteen identical answers out of fourteen — so a thirteen-answer disagreement is far outside run-to-run variation and is genuinely caused by the map.
Which makes the honest reading this: at a million the position map rewrites almost every answer and improves none of them. The two maps place the last token at 447,941 and 251,333 respectively, disagreeing about 1,008 of 1,009 sampled positions, and all that rearrangement buys is a different pair of wrong answers. It is not that the attention layers are ignored — they clearly respond. It is that whatever they contribute at this length is not what decides whether the needle is found.
Those two positions are arithmetic, and checkable:
251,333 = 1,005,333 // 4 for bare division, 447,941 = 262,144 + (1,005,333 − 262,144) // 4 for the faithful prefix. One refinement the sentence above
glosses over: the shipped map does not place the last token at a single
position. Pairs 15–21 carry the earlier stage too and land at 415,173; the
other twenty-six pairs land at 447,941
(receipts/POSITION_MAP_ARITHMETIC_RECEIPT.json).
None of this changes the shipped choice, and the reason it was chosen never depended on the million: below 262,144 the map is the identity and therefore cannot spoil anything inside the trained window, which no other candidate can claim. Above it, neither map is better than the other.
Correction, 2026-07-26. For about an hour this section claimed the two maps produced byte-identical output, and concluded from that that position information never reaches the answer at a million. Both statements were wrong. They came from a comparison script of mine that read a field named
answerfrom receipts whose field is calledanswer_text, so it compared empty strings and reported everything as matching. Re-checked against the right field, one answer of fourteen matches, not fourteen. Every other byte-identical claim in this card was computed with different code and has been re-verified against the correct field: the KV-arena spread and the NOOSPHERE A/B both hold.
Attention temperature was tried and rejected. The value derived for a million, 1.2890, nearly coincides with the 1.2880 that YaRN applies unconditionally at every length. On the shipped map it gave 2/14 against 3/14 without it — both figures from the pre-1.5.0 runtime, where the no-temperature baseline has since dropped to 2/14. So on the current runtime the honest statement is weaker than "it costs a needle": temperature has not been re-measured against the 2/14 baseline, and what can be said is that it never gained one. There is no temperature in the release, and re-measuring it would not change that.
Launching with no flags: verified on 32 GB, broken on 24
Both branches of the selection are verified, each with nothing but the model path on the command line.
FLAGLESS_LAUNCH_HEADLESS_RECEIPT.json, a headless RTX 5090: the full
1,010,001 window chosen, arena 13.15 GB, chunk 4096, position plan applied,
utilisation 0.95. This is the flagship path and it needs no arguments. That
receipt predates the arena change — the shipped figure is 13.00 GB, re-verified
flagless on 2026-07-26 in flagless_after_fix.json, and end to end on a literal
1,010,000-token prefill in million_arena.json.
FLAGLESS_LAUNCH_RECEIPT.json, a desktop RTX 5090 with the graphical session
running: window 393,216 chosen,
codec turboquant_3bit_nc, arena 5.2 GB, chunk 4096, utilisation lowered from
0.95 to 0.927 to fit the memory actually free, NOOSPHERE mode raw. The model
answered.
That check found four bugs, each of which fired only on a machine with a
graphical shell, which is to say on most people's machines: a stepped-down
profile carrying a rigid 0.95 utilisation; a hardcoded vLLM default of 0.9 where
0.25.1 ships 0.92, so an untouched default read as a deliberate choice and the
profile's utilisation was never applied at all; a fit test and a clamp computing
against different margins, so a profile passed selection and was immediately
impossible; and, without skip_mm_profiling, the vision tower's startup
profiling dying in humming_gemm with CUDA_ERROR_INVALID_VALUE.
Not one of them was ever seen by any measurement, because every probe passed its parameters explicitly and went around the profile block.
A 24 GB card is a different story, and it is now measured rather than
unverified. This section previously said a no-flags launch on a 4090 was simply
untested, and reassured the reader that the arena capacity there was comfortable.
That reassurance was wrong. Emulated by ballast on a 5090 at 4090-level free
memory, the bare command used to fail, for three separate reasons set out in
the 4090 note near the top of this card. All three are fixed: the same emulation
now selects 262,144 tokens and answers (ada_expandable.json, ada_control.json,
2026-07-26). Both branches verified above are still 5090 branches, and the 24 GB
branch has never been re-run on Ada silicon — only emulated.
NOOSPHERE is off in the release. A controlled measurement at 250,000 tokens, one machine, only the mode differing: 9 needles of 14 either way, and all fourteen answers matched byte for byte. The mechanism does work — the receipt shows the plan built and biases of 0.1 to 0.65 applied over 82,000 tokens — but they do not change which token comes next. It costs 4% of read time. It goes back on when it changes answers for the better on a measurement rather than on a promise.
Reasoning is off by default
The chat template ships with the thinking block closed. Measured on eight
questions: with the block left open the model closes it only three times in
eight — sometimes it reasons and closes properly, sometimes it answers straight
away and the answer ends up inside an unterminated <think>, which an API then
serves to the user as content. Pass enable_thinking=true in
chat_template_kwargs if you want the reasoning.
Known issue: it stutters when asked what it is based on
Asked in Russian "кто тебя обучал и на чём ты основан", the model answers "LOMONOSOV ZENIT от Dikun International, на основе LOMONOSOV ZENIT LOMONOSOV ZENIT от Dikun International" — the name repeated. Seven of eight identity questions come back clean; this one does not.
It is a trained reflex, not a prompting problem: the identity fine-tune tied "based on" questions to the name, and two rounds of adjusting the default system prompt did not shake it loose. Fixing it properly needs retraining, which is queued rather than rushed. Until then the answer is wrong-looking rather than wrong: the model is indeed LOMONOSOV ZENIT from Dikun International, and the base it was built on is named at the top of this card.
What the model does not have
- GGUF, Ollama, LM Studio, KoboldCpp — unsupported. llama.cpp's converter
does not know the
LomonosovZenitAltayForConditionalGenerationarchitecture, and neither the ALTAY overlay nor the KV codec has an equivalent in the format. - ExLlamaV2 / TabbyAPI — its own attention implementation, unsupported.
- Ampere and older cards — see the table above.
Known behaviour
The KV cache arena is deliberately larger than the declared window. Sized
exactly to the window, vLLM's scheduler is left with no free blocks and drops
into an idle loop: at a million that produced 69–72% idle with the GPU at 13–21%.
The trigger was isolated with a controlled pair of runs and the cure is spare
blocks; the window does not shrink (KV_ARENA_HEADROOM_FINDING.md).
If you set --kv-cache-memory-bytes yourself, leave room above
--max-model-len.
Licence
Released under OpenRAIL. Its use restrictions apply: you may not produce material that breaks the law where you live, or the law of the Russian Federation.
Helping this along
This is one person's project with two graphics cards behind it, and it is going to keep moving whether or not anyone helps. But help is welcome, and there are two kinds.
Work. The open problems are written down in plain sight, including the ones we failed at. Retrieval past a quarter of a million tokens is the big one. Ampere support means requantising the attention path. The 150 ms decode step is 4,192 kernel launches for 44 ms of work, and somebody who knows CUDA graphs better than we do could probably halve it. Issues, pull requests and contradicting measurements are all equally useful — especially the last kind.
Money. If the project is worth something to you and you would rather send a few coins than write code, these are the addresses. Every one of the QR codes below was decoded back off the finished image and compared byte for byte with the address, because a wrong QR is money that cannot be recovered.
| network | address |
|---|---|
| Bitcoin | bc1q5dd03hfghnvzwveaal93jlh98j2wcyk6e42rv3 |
| Ethereum and EVM chains | 0xEb83C6BC7c3a22De82AE71bb490baB9FeBbDf1d2 |
| Solana | 54qC3fsLKnidGmACbt28y5wveEzoxWpZTDkJRDGbJfSJ |
| Tron | TLDtubCQN1bT8k9sWLRu8PAprq4TXhuWbB |
Nothing is gated behind a donation. The weights, the measurements and the tools are the same either way.
LOMONOSOV ZENIT 27B «ALTAY» — INDEV
Что изменилось в этой версии: 1.47 ГиБ видеопамяти, при замеренном паритете
MLP слоёв 32–63 переведён с NVFP4 на несимметричные три бита
(pack-quantized, группа 32, с поиском шага), таблица эмбеддингов — с восьми бит
на четыре. Внимание, рекуррентные слои и зрение не тронуты.
| прежние веса | эти веса | |
|---|---|---|
| файлы на диске | 15.79 ГиБ | 14.32 ГиБ |
| по отчёту движка при загрузке | 16.44 ГиБ | 14.86 ГиБ |
| закладки, 34 140 токенов, 48 игл | 43/48 | 43/48 |
| закладки, 260 148 токенов, 144 иглы | 95/144 | 95/144 |
Обе длины сняты на этой машине, на тех же корпусах, причём прежние веса переснимались в тот же день как опора. Длинное сравнение — парный точный критерий Макнемара по отдельным иглам: шестнадцать игл потеряно, шестнадцать выиграно, p = 1.0000. Короткое: две против двух, p = 1.0000.
Это не «без потерь». Это неотличимо от прежних весов на данной пробе при данных двух длинах. Разрешение прибора замерено: в любом парном сравнении сторону меняют 13–16 игл из 48, то есть мелкой разницы он не видит, и он ничего не говорит про рассуждение, код и устойчивость генерации.
Что на этих весах НЕ переснято. Прежняя карточка несла шесть длин удержания и три числа по пониманию прозы; четыре длины (101 140 · 201 140 · 263 140 · 401 140) и все три числа по прозе замерены на прежних весах и потому здесь не заявляются. Они снимаются заново. Строка миллиона считается прямо сейчас.
Миллион, замеренный на одной машине, парно. Эти веса прошли корпус в 1 006 160 токенов до конца: 11/48 закладок, 48 с на загрузку, 1375 с на префилл. Прежние веса на той же машине, том же корпусе, том же рантайме и при большем запасе свободной памяти (30 964 МиБ против 30 902) не запустились вовсе — нехватка памяти, не хватило 137 МиБ, при том что движок сообщил 16.31 ГиБ весов против 14.86 здесь.
Поэтому строка миллиона — не сравнение: сравнивать не с чем, прежние веса на этой карте при обычном рабочем столе до вопросов не доходят. Замеренное сильнее сравнения: прежние веса миллион здесь не тянут, а эти тянут. Цифра 18.8% из прежней карточки снята на арендованной карте и на корпусе короче на двадцать токенов, а тот же план позиций между машинами расходился до четырёх игл, поэтому 11/48 приводится отдельно и против неё не ставится.
Куда уходит сэкономленное: профилю миллиона нужно примерно на 1.47 ГиБ меньше, а на карте в 32 ГБ это разница между «нужен почти пустой рабочий стол» и «терпит обычный».
Языковая модель на 26 895 998 464 параметра с контекстом
1 010 000 токенов, рассчитанная на одну потребительскую видеокарту. Вместе
со зрительной башней и оверлеем ALTAY в чекпойнте 27 274 981 624 параметра
(receipts/PARAMETER_COUNT_RECEIPT.json).
Это работа в процессе, и карточка говорит об этом там, где это важно. Каждое число ниже измерено на нашем железе и имеет квитанцию. Ничего не оценено на глаз, не экстраполировано и не округлено в свою пользу. Там, где что-то не работает, это написано так же прямо, как и то, что работает.
Что это
Гибридная архитектура: 48 слоёв гейтированного дельта-правила с состоянием фиксированного размера и 16 слоёв полного внимания, GQA — 24 головы запроса на 4 головы KV, размерность головы 256. Наложение ALTAY-72M-SKV: 72 логических слоя поверх 64 физических блоков KV. Веса: текст NVFP4, внимание FP8, зрение FP8, эмбеддинги INT8. Кэш KV трёхбитный TurboQuant, 12.5 КиБ на токен.
Языки: английский, русский, украинский. Ввод картинок работает и замерен: модель
описывает поданное изображение (receipts_vision/).
До 2026-07-26 зрение не работало, и не работало молча. Картинка убивала движок:
cuFuncSetAttribute → CUDA_ERROR_INVALID_VALUEвнутриhumming_gemm. Слои зрения были квантованы целочисленнымpack-quantizedс размером группы 16, а на Blackwell такую группу принимает ровно одно ядро —humming, — и оно там не запускается. Marlin берёт −1/32/64/128, Conch −1/128, Machete и CUTLASS требуют Hopper, AllSpark не знает sm_120. В профилях стоялskip_mm_profiling, и он прятал то же падение при старте, поэтому никто не жаловался, пока не подашь настоящую картинку. Никто и не подавал.Перейти на группу 128 тоже нельзя: у
linear_fc2вход 4304 = 16 × 269, и 269 простое.Замеренная лестница, живая карта, одна картинка, один вопрос:
схема зрения шард итог целочисленная, группа 16 (было) 331 МБ движок падает NVFP4, группа 16 254 МиБ жив, отвечает !!!!!FP8 поканально (отгружается) 445 МиБ верное описание BF16 без квантования 879 МиБ верно и подробнее NVFP4 закрыт замером: средняя ошибка веса 10.78%, и это собственная погрешность формата на таком распределении — расчёт масштабов сверен с эталонным из библиотеки и совпал. Литература говорит то же про активации, которые мы заодно квантовали: RepQ-ViT (arXiv:2212.08254), ADFQ-ViT (2407.02763) и APHQ-ViT (2504.02508) все называют активации после LayerNorm и GELU тем местом, где четырёхбитные ViT умирают. Четыре бита достижимы, но через калибровку, а не округлением к ближайшему.
Миллион правку пережил. Проверено без единого флага на пустой 5090: веса 14.86 ГиБ, кэш KV 1 017 164 токена, выбрано окно 1 010 001, модель отвечает.
Бейдж «model size» наверху показывает около 17B. Не верьте ему. Hugging Face считает элементы тензоров так, как они лежат в файле, а почти все веса здесь упакованы по нескольку в элемент. Если считать правильно — восстанавливая исходную ширину каждого тензора по форме его таблицы масштабов, при этом неразрешённых тензоров не остаётся ни одного:
| параметров | |
|---|---|
| упаковано по четыре бита | 24 054 511 616 |
| упаковано по восемь бит | 1 504 074 752 |
| без упаковки: внимание FP8, нормировки и смещения BF16 | 1 716 395 256 |
| всего | 27 274 981 624 |
| из них языковая часть | 26 895 998 464 |
| зрительная башня | 371 380 976 |
| оверлей ALTAY | 7 602 184 |
Эмбеддинги не связаны (tie_word_embeddings: false), поэтому embed_tokens и
lm_head весят по 1 271 398 400 и считаются порознь — двойного счёта нет. В
файлах ничего не пропало: 2 509 тензоров, ровно столько же в
model.safetensors.index.json, у каждого шарда заголовок сверен с длиной файла
после скачивания обратно с Hub.
Исправлено 2026-07-26. Здесь число выводилось так: «11.96 миллиарда байт, в них 23.9 миллиарда параметров, прибавьте 3.17 миллиарда FP8» — а это в сумме 27.07 миллиарда, а вовсе не то число, которое абзац брался получить. Считались при этом все
U8как четырёхбитные, хотя эмбеддинги восьмибитные, а зрение смешанное. И тензоров стояло 2 503. Заголовок же называл 26 895 998 464 размером мультимодальной модели, тогда как это ровно тот счёт, из которого мультимодальная часть исключена. Первоисточника у числа не было нигде в репозитории — теперь оно замерено (receipts/PARAMETER_COUNT_RECEIPT.json, воспроизводитсяcount_parameters.py), и оказалось в точности размером языковой части.
Построена на Qwen3.6-27B от Alibaba, затем переквантована и получила наложение ALTAY и расширенное окно. Разработка шла с оглядкой на практики ChatGPT 5.6 Sol Max и Kimi K3, причём фронтенд — по образцу Kimi K3. Мы называем всех троих, потому что происхождение это часть карточки, а не сноска, которую надо искать.
Исправлено 2026-07-26: окно миллиона не поднималось из коробки, и все его замеры сделаны с переменной, которой в поставке нет.
Профиль
raw_1010kобъявлял окно 1 010 001 токен, а модель — ёмкость 1 010 000. Разница в один токен, и vLLM отказывается стартовать:ValidationError: User-specified max_model_len (1010001) is greater than the derived max_model_len. Всякий, набравшийvllm serve <модель>на 5090, получал это вместо флагманского окна.Не всплывало потому, что все пять наших проб выставляют
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1сами, а отгружаемый рантайм не выставляет её нигде. Сертификат и вся кривая удержания сняты в конфигурации, которой у пользователя нет. Наша же проверка «без флагов» тоже прошла мимо: та проба зажимает память, поэтому отбор всегда останавливался на 262 144 или 393 216 — окнах ниже объявленной ёмкости, где проверка не срабатывает. Инструмент, созданный искать дефекты запуска, по своему устройству не мог найти этот.Починено и замерено: объявленная ёмкость теперь 1 010 001, арена кэша урезана с 13.15 до 13.00 ГБ — она была завышена против окна, которому нужно 12.03 ГиБ. Без флагов, без переменной и без чего-либо ещё на карте движок выбирает 1 010 001, отводит кэш на 1 017 164 токена и отвечает.
Здесь стояло, что случай занятой карты починить нельзя. Это было неверно, и он починен — исправлено 2026-07-26. Стояло дословно: «Никакой порог их не разделит; мы пробовали два и замерили, что оба не работают.» Порог разделяет их в точности. Не хватало не порога, а замера того, что отбор видит на самом деле, — и этого замера мы ни разу не делали.
Неверных вещей было три сразу. Движку не хватало 80 МиБ, тогда как 377 МиБ лежало зарезервировано и не занято: память на карте была, её раздробил распределитель. Арена кэша несла 130 МиБ ненужного запаса. А объявленная потребность профиля была оптимистичнее на 168 МБ, из-за чего миллион выбирался на картах, которые его не тянут.
Все три исправлены: профиль просит расширяемые сегменты распределителя (публикуются до первого выделения памяти CUDA и никогда не поверх вашего значения), арена равна 13.00 ГБ, а
requires_free_bytes— это последний бюджет, при котором миллион замеренно поднялся и ответил. Проверено лестницей из девяти уровней занятости: примерно до 640 МиБ, занятых чужими процессами, миллион выбирается и работает; выше — движок шагает на 393 216 и работает. Уровня, на котором он выбирается и падает, больше нет.Чего это не делает — не заставляет миллион работать на занятой карте. Оно делает отказ честным. Если что-то держит больше примерно 0.64 ГиБ, вы получите 393 216 токенов, а не падение; а если нужен именно миллион — освободите карту.
Все квитанции, названные в карточке поимённо, лежат вместе с моделью — в
receipts/. В каждой записан вопрос, на который она отвечает,
машина, где снималась, и — это важнее всего — чего она не устанавливает. Там,
где две квитанции расходятся (а одна такая пара есть), указатель папки говорит,
какую из них берёт карточка и почему.
На чём запускается
| карта | память | контекст | откуда число |
|---|---|---|---|
| RTX 5090 | 32 ГБ | 1 010 000 | измерено |
| RTX 4090 | 24 ГБ | ~365 000, и только с явными флагами | измерено, ADA_SM89_RECEIPT |
| RTX 6000 Ada / PRO 6000 | 48 ГБ | не проверялось | такой карты у нас нет; лестница профилей выберет самый широкий из подходящих |
| RTX 3090, A6000, A100 | — | не загрузится | схема FP8 в vLLM требует compute capability 8.9 |
История с 4090, исправлено 2026-07-26. В этой строке стояло, что 4090 сама выбирает окно 393 216. Это неверно, и неверно в самом больном месте: именно автоматический выбор карточка и предлагает как удобство.
С явными флагами настоящая 4090 работает:
--max-model-lenи доля 0.92 дают арену на 365 524 токена при префилле 790.7 т/с (ADA_SM89_RECEIPT).Без флагов она не запускается. Арендовать карту Ada повторно не удалось, поэтому замер сделан балластом на 5090: память занималась до уровня 4090, после чего давалась голая команда. Отбор берёт
long_393k, и движок умирает от нехватки памяти в автотюнере FP4. Принудительныйlong_262kпадает раньше и с другой ошибкой.Лестница обхватывает порог с точностью до 199 МБ:
long_393kтребует около 25.5 млрд байт свободных на отборе, а объявляет 24.05 млрд — занижение примерно на 1.4 ГБ. У 4090 всего 25.76 млрд, и после драйверного резерва с одним контекстом CUDA остаётся около 25.0–25.2 млрд, то есть на несколько сотен мегабайт ниже черты.Три отдельные причины, все установлены:
requires_free_bytesбыл взят оценкой, а не замером, и занижен примерно на 1.5 ГБ у обоих затронутых профилей; закреплённаяkv_cache_memory_bytesзаставляет vLLM пропустить профилирование памяти целиком, поэтому прижатие доли на тесной карте ничего не меняет; а уlong_262kвообще не было поляgpu_memory_utilization, прижимать было нечего, и вступало умолчание vLLM 0.92, требующее больше, чем есть на карте.Починено, и починка замерена. Пороги найдены балластной лестницей, отбор проверен сквозным прогоном на четырёх уровнях памяти — см. таблицу профилей ниже. 24-гигабайтная карта теперь сама выбирает 262 144 токена без флагов и работает. В строке выше по-прежнему стоит «с явными флагами», потому что само число окна, ~365 000, снято на живой карте Ada и с тех пор не переснималось; а путь без флагов починен.
Окно выбирает сама модель, по фактически свободной памяти вашей карты. Если объявленный миллион не влезает, берётся самый широкий из подходящих профилей и в лог уходит одна строка с объяснением.
На 32-гигабайтной карте это работает и замерено — и безголовой, и с графической
сессией. На 24 гигабайтах тоже работает, и эта фраза заменяет прежнюю, где
стояло «не работает»: требования профилей пересняли, и голая команда теперь
выбирает 262 144 токена и отвечает. Подтверждено заново на релизной сборке
2026-07-26 (ada_expandable.json, ada_control.json) — балластом на 5090, а не
на кремнии Ada, тем же инструментом, который дефект и нашёл.
Про миллион на 5090 честно. Веса занимают 14.86 ГиБ — это цифра самого движка при загрузке, а не размер файлов, который 14.32 ГиБ, — арена кэша 12.11 ГиБ, вместе 26.97 ГиБ. Замеренный пик всего процесса на миллионе — около 30.0 ГиБ при карте в 31.84: остальное уходит на активации и рабочие буферы. То есть под рабочий стол остаётся примерно 1.8 ГиБ. Замерено грубо и честно: три попытки подряд отказали с нехваткой памяти, когда браузер и сторонние приложения держали около 1.6 ГиБ, и прошли, когда их закрыли. На прежних весах порог был жёстче — там миллион требовал примерно на 1.47 ГиБ больше и не поднимался почти ни при каком рабочем столе. Сейчас обычная графическая сессия его уже не блокирует, но запас небольшой: тяжёлый браузер или второе приложение на карте по-прежнему уронят запуск, и модель шагнёт на меньшее окно сама — это задуманное поведение. Закройте графическую сессию или отдайте дисплею вторую карту.
Установка
pip install vllm==0.25.1
pip install https://huggingface.co/Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV/resolve/main/lomonosov_zenit_altay_runtime-1.5.0-py3-none-any.whl
vllm serve Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Средняя строка не необязательная, и появилась она здесь 2026-07-26. Без неё
vllm serve не стартует вовсе: Model architectures ['LomonosovZenitAltayForConditionalGeneration'] are not supported. Архитектура
ALTAY, профили запуска, кодек TurboQuant и карта позиций живут в этом пакете на
88 КБ, а поставить его из репозитория модели сам vLLM не умеет. Проверено с обеих
сторон: если пакет спрятать — движок отказывает ещё на разборе конфига; если
поставить одно только колесо — архитектура разрешается и профиль применяется.
Весов в колесе нет, только код.
Если каталог модели уже лежит на диске, pip install <каталог модели> делает то
же самое.
Патченный vLLM не нужен: бэкенд TurboQuant едет в публичном колесе, шесть файлов
совпали по sha256 между двумя независимыми установками
(STOCK_VLLM_BACKEND_RECEIPT).
vLLM — единственный работающий путь, а карточка намекала на другое. До 2026-07-26 здесь стояло
library_name: transformers, и Hub предлагал сниппет «Use with transformers». Этот сниппет падает: архитектуру ALTAY регистрирует плагин к vLLM и больше никто,auto_mapв конфиге нет, поэтомуAutoModelForCausalLM.from_pretrainedоткатывается на стоковыйqwen3_5, который не умеет читать упакованные в восемь бит эмбеддинги, — и умирает с'Embedding' object has no attribute 'weight'(receipts/try_transformers.json). В метаданных теперьvllm. Реализация ALTAY на стороне transformers этот путь открыла бы; её пока нет.
На прогретой машине движок готов примерно за 53 секунды — медиана по 86 записанным запускам, основной разброс от 49 до 77 секунд. Из них чтение весов занимает 4.4 секунды: 14.86 ГиБ на скорости около 3.7 ГБ/с, то есть уже скорость NVMe, и оптимизировать там нечего. Мы это проверяли, потому что ускорение загрузчика весов стояло в списке работ; замер задачу и закрыл. Остальное — инициализация движка.
Первый запуск на новой машине занимает на 4 минуты дольше — vLLM собирает
ядра FP4 под вашу карту: 18 единиц трансляции, на выходе
fp4_gemm_cutlass_sm120.so размером 5.4 МБ. Замерено на RTX 5090. Платится один
раз на машину и на версию FlashInfer, дальше берётся из ~/.cache/flashinfer.
Модель сама ограничивает параллельность этой сборки по доступной оперативной
памяти. Без ограничения компилятор запускает по числу ядер, каждая единица
трансляции просит около 6 ГБ, и на машине с обычным объёмом ОЗУ сборку убивает
OOM-killer — в логе это выглядит как Engine core initialization failed, а
настоящая причина (code=137) лежит на несколько сотен строк выше и ни на что не
указывает. Ограничитель выбирает clamp(1, min(ядра, доступно / 6 ГБ), 8) и
печатает одну строку с причиной; ваш собственный MAX_JOBS он не трогает
(FIRST_RUN_JIT_RECEIPT).
Сколько ждать
Главное, что нужно знать до запуска: длинный контекст читается минутами.
RTX 5090, заводские частоты, кодек turboquant_3bit_nc, одна последовательность.
| контекст | сколько читается | токенов в секунду |
|---|---|---|
| 131 072 | 34 с | 3840 |
| 262 144 | 109 с | 2400 |
| 524 288 | 381 с (6.4 мин) | 1375 |
| 1 010 000 | 22 мин | 768 |
Переснято 2026-07-26, и прежняя строка была медленнее самой модели. Здесь стояло 2496 / 1799 / 1140 / 648. У этих чисел не было квитанции в репозитории — сплошная сверка всех цифр карточки пошла её искать и не нашла, — и сняты они были до правок арены, плана позиций и распределителя. Замер на релизной сборке с
max_tokens=1показал, что модель на 18–54% быстрее, чем утверждала карточка (receipts/prefill_table.json, воспроизводитсяprefill_table.py).Одну ловушку замера стоит передать дальше: первый запрос в свежем процессе компилирует ядра Triton прямо на ходу. На холодную 131 072 токена дают 2277 т/с, после одного прогревочного запроса — 3840. Та же работа, разница 41%. В таблице стоит прогретое число, потому что именно его выдаёт работающий сервер. Первый запрос пользователя будет медленным.
RTX 4090: 32 768 токенов за 38 с (861 т/с).
Спад с ростом контекста — квадратичная стоимость внимания, а не изъян реализации: 381 с на 524 288 токенах быстрее чистой квадратичной экстраполяции от 262 144.
Второй вопрос по тому же тексту почти бесплатен. Кэш префикса даёт 16.9× / 52.9× / 172.9× — так здесь было напечатано.
На миллионе этого не ждите — исправлено 2026-07-26. Неверными оказались две вещи. У этих ускорений не сохранилось квитанции в репозитории: сплошная сверка чисел карточки пошла её искать и не нашла. И кэш префикса в профиле
raw_1010kвыключен, поэтому на отгружаемом умолчании второй вопрос по миллиону стоит ещё одно полное чтение, а не 7.5 секунды.Включение его не спасает, а делает хуже, и теперь понятно почему. С кэшем префикса полезная арена падает до 1 010 001 токена — это 489 блоков при 490, которые нужны окну. Кэш перестаёт вмещать то окно, под которое рассчитан, и движок встаёт: замерено, 53 минуты при нулевой загрузке карты, после чего прогон снят. Это тот же отказ «арена теснее окна», доведённый до конца.
Ниже миллиона, где в арене есть место, кэш префикса включается флагом
--enable-prefix-caching, и второй вопрос действительно дёшев — но насколько, мы не переснимали, поэтому числа здесь не приводим.
Скорость генерации
Около 150 мс на токен, то есть примерно 6–7 токенов в секунду, почти независимо от длины контекста (8К — 154 мс, 131К — 169 мс). Это медленно, и причина известна: за один шаг запускается 4 192 ядра GPU при 44 мс собственно работы, то есть карта большую часть шага ждёт хост. Трёхбитный кодек KV стоит 36% шага: на fp8 шаг занимает 107 мс.
Мы это не скрываем и не выдаём за оптимум. Модель имеет смысл там, где важно прочитать много, а не быстро наговорить.
Графы CUDA выключены осознанно: замер дал 282 мс против 180 при их включении. Профиль шага с этим спорит, и перепроверка стоит в плане.
Удержание контекста
Снято на ПРЕЖНИХ весах (NVFP4 везде, 15.79 ГиБ). Эти веса — другие; переснято пока только 34 140 и 260 148, см. раздел «Что изменилось» выше. Остальное снимается заново.
Мерялось на настоящей русской прозе двумя независимыми инструментами. Оба проверены на коротком контексте прежде, чем применяться к длинному.
Закладки. В прозу на известных глубинах вставлены четырнадцать записей вида «Особая заметка номер 7: код доступа к архиву — ЯНТАРЬ-6421», и по каждой задан вопрос. Ответа нет больше нигде в тексте, так что угадать нельзя.
Чтение прозы. Вопросы строятся механически из самого текста книги: берётся фраза с одним затёртым редким словом. Каждый вопрос сначала задаётся без книги, и то, на что модель отвечает по памяти о классике, из зачёта исключается.
Эта таблица переснята заново 2026-07-26 на корпусе с 48 закладками. В прежней
редакции их было четырнадцать, и замерено, что одиночный прогон на четырнадцати
стоит ±14 пунктов: два прогона без единого изменения дали 9/14 и 7/14. Прежние
числа не поправлены, а убраны — другой инструмент это не уточнение той же
величины. Метод: PROBE_NONDETERMINISM_FINDING.md.
| контекст | найдено закладок | прогонов | первая половина | вторая | прежний план |
|---|---|---|---|---|---|
| 34 140 | 42/48 = 87.5% | 3, совпали | 66/72 | 60/72 | 87.5% (план не активен) |
| 101 140 | 44/48 = 91.7% | 1 | 22/24 | 22/24 | 79.2% |
| 201 140 | 42/48 = 87.5% | 1 | 20/24 | 22/24 | 66.7% |
| 263 140 | 33/48 = 68.8% | 3, совпали | 51/72 | 48/72 | 60.4% |
| 401 140 | 37/48 = 77.1% | 2, совпали | 34/48 | 40/48 | 58.3% |
| 1 006 140 | 9/48 = 18.8% | 1 | 8/24 | 1/24 | 2.1% |
Арендованная RTX 5090, трёхбитный кэш, отгружаемый план позиций. Там, где строка снята трижды, счёт совпал точно во всех прогонах — на одной машине и одной арене эта проба воспроизводит себя, и это утверждение сильнее любой погрешности. Одиночные прогоны помечены одиночными. Между разными машинами один и тот же план расходится до четырёх закладок, поэтому хост назван намеренно.
Крайний правый столбец — план, с которым модель отгружалась до 26.07.2026. В тот день планы позиций заменены, для каждого профиля свой, и прибавка составила от четырёх до десяти закладок везде, где план работает. Оба столбца сняты на одном корпусе, одной машине и одной пробой; различается только план.
Три вещи, которые говорит эта таблица.
Удержание падает с длиной не так, как показывала прежняя кривая. На 201 140 токенах модель держит 87.5% — столько же, сколько на 34 140. Прежний спад с 87.5% до 66.7% на этом промежутке выглядел свойством модели; в основном он оказался свойством плана, чьи ступени начинались с 196 608 и на большей части промежутка не делали ничего. Новый план для этого окна сжимает среднюю полосу частот начиная с 65 536.
Миллион по-прежнему не окно поиска, даже вдевятеро лучше прежнего. Девять закладок из сорока восьми. Считайте миллион возможностью префилла и пропускной способности: модель действительно принимает 1 006 140 токенов и отвечает, но не ждите, что она найдёт факт, положенный в середину. План, дающий 18.8%, делит позиции на шестнадцать за отметкой 212 000 — оттого его вторая половина почти пуста: там шестнадцать соседних токенов делят одну позицию, и различить их нечем.
Провал на 263 140 настоящий, и это краевой эффект, а не огрех замера. Этот
корпус на тысячу с лишним токенов длиннее окна 262 144 профиля long_262k,
поэтому мы пересняли внутри окна, на корпусе в 260 140 токенов: 33/48, ровно
столько же. Переход границы не стоит ничего; стоит приближение к ней. У пар,
которых полоса не покрывает, позиции родные, и счёт следует за тем, какую долю
обученного диапазона они занимают: 101 140 — это 38.6% и 91.7%, 201 140 — 76.7% и
87.5%, 260 140 — 99.2% и 68.8%. Удержание падает по мере заполнения обученного
окна, ещё не выходя за него.
Плотность закладок по строкам не постоянна: их всегда сорок восемь, поэтому на 34 140 это 140.6 факта на 100К токенов, а на 401 140 — 12.0. Длина и плотность в этой таблице меняются вместе по устройству пробы.
Изменилась одна строка плана позиций. Пары частот, совершающие от одного до тридцати двух оборотов на обученном окне — пары 15…21 из 32, — получают вдвое сжатые позиции выше 196 608, а остальные двадцать пять держат истинные до 262 144. На одном хосте и одном корпусе прежняя карта даёт 10/14, новая 13/14: три записи приобретены, ни одна не потеряна.
Три вещи здесь заслуживают вашего скепсиса, и мы разделяем все три.
Прибавка найдена перебором шести префиксов с показом лучшего, а это отбор по результату — поэтому её переснимали на другом корпусе, который в выборе не участвовал, и там она дала те же три записи.
Механизм не понят. Сжатие участка, где нет ни одной записи, всё равно меняет, какие записи находятся, так что это не «мы починили углы закладкам». Четыре записи из четырнадцати стоят на грани решения, и любое возмущение их двигает; это сдвинуло их в одну сторону дважды, на двух корпусах.
И это не тот опубликованный метод, на который похоже. Поиск подсказан DPE (arXiv:2504.18857), где предписано ранжировать измерения по замеренной 2-норме вклада во внимание и переназначать позиции верхней половине. Мы это ранжирование замерили — 16 слоёв внимания, реальные активации, с проверкой, что понарная нарезка воспроизводит норму всей вращаемой части на каждом слое. Оно почти плоское, от 1.4% до 7.0% на 32 пары, с числом оборотов не связано, а сжимаемые нами пары стоят в нём 32-м, 31-м, 27-м и 20-м. Отбор по критерию статьи даёт 11/14 против наших 13/14. Значит отгружаемый диапазон — эмпирическая находка, названная по статье, которая натолкнула на поиск, а не её применение.
Миллион не изменился, 2/14. Карта там ничего не стоит и ничего не даёт; за обученным окном предел, судя по всему, архитектурный.
Не читайте 92.9% как «понимает четверть миллиона токенов». Два инструмента расходятся, и это расхождение — самое честное, что здесь можно сказать. На том же корпусе, той же длины и в той же отгружаемой конфигурации чтение прозы даёт 2 из 12. Без карты — 1 из 12, то есть она помогает и здесь, но на один вопрос, что при таком знаменателе едва отличимо от нуля.
Найти вставленную строку и ответить на вопрос по книге — разные задачи, и модель стала заметно лучше в первой, оставшись слабой во второй. Если ваша работа — это поиск: вытащить пункт, найти запись, отыскать ссылку, — значение имеет 92.9%. Если ваша работа — рассуждать по четверти миллиона токенов прозы, то 16.7%.
Исправление от 2026-07-26. До сегодняшнего дня в этой строке стояло 21.4%
(3/14). То число снято на рантайме до 1.5.0. На отгружаемом та же конфигурация
даёт 2 из 14, и это не пограничный случай: шесть независимых прогонов — пять
повторов релизной карты и один голого деления на четыре — вернули 2/14 с
побайтово одинаковыми ответами. Две квитанции носят один ярлык
faithful262k_g4_1m по разные стороны смены рантайма, одна с 3/14, другая с
2/14. Публикуется то число, которое отгружаемый артефакт воспроизводит.
Одной длины недостаточно, чтобы предсказать точность. Она зависит ещё и от того, сколько в тексте однотипных записей. Это другое семейство корпусов, с более плотной вставкой, чем в таблице выше, — сравнивайте колонки между собой, а не с кривой выше:
| длина ↓ / записей → | 4 | 8 | 14 | 40 |
|---|---|---|---|---|
| 33 000 | 78.6% | 82.5% | ||
| 250 000 | 100% | 75% | 64.3% | 60.0% |
| 1 005 000 | 25% | 14.3% |
На четверти миллиона прореживание помогает сильно: четыре записи находятся все четыре. На миллионе оно уже не помогает. Строка миллиона снята до рантайма 1.5.0, кроме клетки на четырнадцать записей — она переснята.
Модель, про которую было заявлено, что она подходит, а она не подходит. В более ранней версии этой карточки стояло: если нужная запись выигрывает лишь тогда, когда её отклик выше, чем у всех остальных N−1 позиций — вероятность Φ(Δ/σ)^(N−1), — то одно подобранное отношение запаса к шуму 4.666 воспроизводит все три замеренные точки. Так и выглядело, но лишь потому, что три точки были взяты из трёх разных мест: 92.9% с одного корпуса, 64.3% с более плотного корпуса выше и 21.4% со старого рантайма. Подобранная к любой тройке точек, которые действительно принадлежат друг другу, однопараметрическая модель промахивается крупно:
| тройка | лучшее Δ/σ | наибольший промах |
|---|---|---|
| кривая до ступенчатой карты, 92.9 / 78.6 / 14.3 | 4.670 | 10.0 пункта (250 000 занижено) |
| плотный корпус, 78.6 / 64.3 / 14.3 | 4.576 | 13.9 пункта (33 000 завышено) |
То есть взаимные помехи между однотипными записями — эффект настоящий, и он объясняет горизонтальную ось: прореживание с четырнадцати записей до четырёх поднимает 250 000 с 64.3% до 100%. Вертикальную ось он не объясняет. Тем, что происходит с ростом длины, управляет что-то помимо тесноты, и это сходится с остальной карточкой: за обученным окном предел ставит состояние фиксированного размера сорока восьми гейтированных слоёв, а его прореживанием помех не сдвинуть.
Что это значит для вас. Миллион токенов модель прочитает целиком, без выбрасывания и без конспекта, и это подтверждено сквозным прогоном. Но рассчитывать, что она найдёт нужную строчку в начале миллионного документа, нельзя. Надёжный поиск — до примерно четверти миллиона токенов, и тем надёжнее, чем меньше в тексте однотипных записей: на 250 000 это от 64% при четырнадцати конкурирующих записях до 100% при четырёх. Дальше модель читает, но находит плохо: около одной пятой на миллионе независимо от числа фактов, и найденное лежит в последних примерно 150 тысячах токенов.
Трёхбитный кэш ничего вам не стоит по точности
Разумное подозрение: контекст хранится в трёх битах на значение, не платим ли мы за это качеством поиска. Проверено напрямую — один корпус, одна длина 250 000, одна карта позиций, отличается только формат хранения:
| KV | байт на токен | найдено |
|---|---|---|
| трёхбитный TurboQuant (в выпуске) | 12 785 | 24/40 |
| fp8, практически без шума кванта | 32 768 | 28/40 |
Разница в десять пунктов, но руки прогонялись по одним и тем же закладкам, поэтому правильный критерий парный: десять расхождений, семь против трёх, точный критерий Макнемара p = 0.34. Не значимо. Красноречивее самого p: двадцать одну закладку нашли обе руки, а девять не нашла ни одна, даже при безшумном кэше. Эти девять теряются в конкуренции похожих записей, а не в шуме хранения.
Почему в чекпоинте не YaRN
Модель обучена на 262 144 позициях. Объявленный миллион — расширение без обучения: 262 144 × 3.85284 = 1 010 000 ровно.
Промежуточная сборка везла YaRN с этим коэффициентом, и это стоило точности внутри обученного окна. Замерено на одном корпусе, одном усечении, при единственном отличии — карте позиций:
| на 250 000 токенах | закладок | точность |
|---|---|---|
| YaRN, как было | 9/14 | 64.3% |
YaRN с attention_factor = 1 |
10/14 | 71.4% |
| родные позиции | 11/14 | 78.6% |
YaRN делает две вещи, и каждая стоила примерно по закладке. Он безусловно множит
логиты внимания на 1.288 при любой длине входа, включая короткую, — модель
такого не видела. И он сжимает десять самых медленных пар частот из тридцати
двух, тогда как при rope_theta = 1e7 самая медленная пара не проходит и трёх
процентов оборота на всём миллионе, то есть сжимать там нечего.
Поэтому выпуск идёт на родных позициях, а окна шире обученного получают позиции иначе — см. ниже.
RazorAttention: 6.3 ГБ видеопамяти, и чем за них платят
Модель везёт custom_generate/razor_attention.py. По умолчанию он выключен, и
включать его стоит только зная цену — она замерена.
Устройство. Кэш KV занимает 13 ГБ и весь приходится на 16 слоёв полного внимания;
остальные 48 — Gated DeltaNet с состоянием постоянного размера, кэша не имеют. Это
0.81 ГБ на слой. Замер поисковых голов (RETRIEVAL_HEADS_DENSE.json, критерий
копирования из arXiv:2404.15574) дал 18 голов из 384, и лежат они в семи слоях из
шестнадцати. Девять слоёв не содержат ни одной. Скользящее окно на этих девяти
освобождает 6.3 ГБ.
Цена, замеренная 26.07.2026 на 260 140 токенах, 48 закладок, отгружаемый план позиций:
| окно на девяти слоях | найдено | первая половина | вторая |
|---|---|---|---|
| выключено (полный кэш) | 33/48 = 68.8% | 17/24 | 16/24 |
| 131 072 токена | 22/48 = 45.8% | 0/24 | 22/24 |
Читать надо не итог, а столбцы половин. Первая половина контекста выносится подчистую — ноль закладок из двадцати четырёх. И это при окне в 131 072 токена, то есть в половину длины контекста; более раннее измерение при окне в 12% длины дало то же самое по сути. Вторая половина при этом даже улучшилась, с 16 до 22: меньше конкуренции за внимание.
Механизм отсюда виден прямо. Девять слоёв без поисковых голов теряют всё, что вне окна, а начало контекста вне окна всегда, пока окно меньше контекста. Никакой размер окна этого не меняет: экономия и потеря — одна и та же ручка.
Включение:
ZENIT_RAZOR_WINDOW=4096 vllm serve <модель>
Две оговорки, из-за которых метод не закрыт окончательно. Реализовано голое
скользящее окно; стоки внимания и компенсирующий токен из статьи
(arXiv:2407.15891) в SlidingWindowSpec не выражаются, а стоки — это как раз
первые токены, то есть то, что голое окно и выбрасывает. И замер сделан на
четырнадцати закладках, до того как выяснилось, что там разброс ±14 пунктов;
на корпусе из 48 он не переснимался.
Берите эти 6.3 ГБ, если вам нужна память под что-то другое и вы готовы к потере дальнего поиска. Для длинного контекста — не берите.
Запуск через transformers
Модель загружается: AutoModelForImageTextToText.from_pretrained с
trust_remote_code=True собирает LomonosovZenitAltayForConditionalGeneration,
накладка ALTAY на месте, упакованные эмбеддинги разворачиваются, 12.7 с, 18.2 ГБ.
Класс мультимодальный, и это существенно: AutoModelForCausalLM строит текстовое
дерево под model.*, тогда как веса лежат под model.language_model.*, и не
совпадает ни один ключ из 853.
Но прямой проход через transformers требует около 55 ГБ. Это не наш недочёт:
у compressed-tensors в transformers нет квантованных ядер, и первый же forward
разворачивает всю модель в bf16 — так объявлено в её собственных исходниках
(model_compressor.py, «This allows for generation without requiring CT to handle
quantized kernels»). Выгрузка в оперативную память не помогает: разворачивание
идёт на месте, после раскладки по устройствам.
Итог: через vLLM модель занимает 17–18 ГБ и работает на одной потребительской карте; через transformers она загружается на 18 ГБ, но считает только на машине от 64 ГБ. Оба числа верны, и путать их не надо.
Профили запуска
Модель везёт параметры запуска в собственном config.json. Порядок выбора:
- переменная
ZENIT_SERVING_PROFILE; - явный
--max-model-len— берётся наименьший профиль, который его вмещает; - иначе самый широкий профиль, влезающий в фактически свободную память (проба через NVML, без создания контекста CUDA);
- иначе профиль по умолчанию.
Любое значение, заданное вами в командной строке, всегда сильнее профиля, и каждая подстановка пишется в лог.
| профиль | окно | требуется свободной памяти | замер |
|---|---|---|---|
raw_1010k |
1 010 001 | 32.34 ГБ | порог замерен с точностью 27 МБ |
long_393k |
393 216 | 25.57 ГБ | порог замерен с точностью 199 МБ |
long_262k |
262 144 | 23.97 ГБ | порог замерен с точностью 510 МБ |
Все три требования замерены, а не оценены, и это изменение. До 2026-07-26 они были оценками, и обе занижены примерно на 1.5 ГБ — настолько, что отбор предлагал профили, которые карта не поднимет. Балластная лестница на арендованной 5090 нашла настоящие пороги: память удерживалась на последовательных уровнях, и на каждом давалась голая команда.
Весь отбор теперь проверен сквозным прогоном на четырёх уровнях памяти: при 26.57 ГБ свободных выбирается окно 393 216 и работает; при 25.67 и 24.47 выбирается 262 144 и работает; при 23.17 не подходит ни один профиль, и лог говорит об этом поимённо и с цифрами, прежде чем остановиться. Последний случай правильный, а не сломанный: одни веса занимают 14.86 ГиБ, и карта с 21 ГиБ свободных не поднимет эту модель ни при каком окне.
У long_262k теперь есть и явная gpu_memory_utilization. Без неё прижимать было
нечего, и умолчание vLLM 0.92 просило больше, чем есть на тесной карте. Обе правки
нужны вместе — каждая по отдельности замерена и не работает.
Требование raw_1010k теперь тоже замерено, а стоявший здесь абзац был неверен
дважды — исправлено 2026-07-26. В нём говорилось: «Инструмент не может измерить
этот профиль: он съедает ровно тот запас, который проверяет.» Может. И полоса
непроверенного была названа шириной 304 МБ, а это число — плод той же ошибки:
проба читала свободную память через torch.cuda.mem_get_info(), а этот вызов
создаёт в её собственном процессе контекст CUDA примерно на 498 МиБ. Чтение
драйвера через nvidia-smi не стоит ничего, и замер становится обыкновенным.
Замеренное так объявленное значение оказалось занижено на 168 МБ, и следствие было именно то, которое важно: миллион предлагался картам, которые его не поднимут. Отгружаемое теперь число, 32.34 ГБ, — последний бюджет, при котором миллион замеренно поднялся и ответил; на 27 МБ ниже движок стартует и умирает на первом запросе.
Урок не про этот профиль. Каждое «это измерить нельзя» в карточке заслуживает такого же недоверия: дважды подряд препятствием оказывался инструмент, а не предмет.
План позиций везёт каждый профиль, и с 2026-07-26 он двухступенчатый: пары 15…21 из 32 частотных пар делят свои позиции на два выше 196 608, а все пары делят на четыре выше 262 144.
Внутри обученного окна это больше не тождество, и в этом всё дело. Прежний план был тождеством — он не трогал ничего ниже 262 144, — и именно поэтому шесть попыток улучшить поиск ни разу не сдвинули 250 000: все они различались только выше отметки, до которой замер не доходил. Первая ступень достаёт внутрь, и именно она подняла 250 334 токена с 10/14 до 13/14.
Ниже 196 608 карта по-прежнему тождественна, так что короткие запросы не затронуты — и это замерено, а не заявлено: рука на 33 334 возвращает ответы, побайтово совпадающие с прогоном вообще без плана.
Вторая ступень выбиралась на миллионе, и там не помогло ничто. На 1 005 334 токенах, четырнадцать закладок, одна машина, отличается только карта: YaRN 0/14, деление на 4 по всем парам 3/14, по медленным парам 2/14, на 8 — 2/14, на 16 — 1/14, зажим медленных пар на границе окна 0/14, отгружаемая карта 2/14. Двухступенчатая там тоже даёт 2/14 — на миллионе она ничего не стоит и ничего не даёт.
Первая ступень, та самая, что решает, выбиралась на 262 334 и проверена на 250 334 — на корпусе, который в выборе не участвовал. Этот поиск описан выше, в разделе про удержание.
В более ранней версии этой карточки всё между единицей и тройкой объявлялось неразличимым на том основании, что инструмент гуляет примерно на две закладки. Это число было неверным: оно получено сравнением двух разных машин и содержало разницу машин, а не шум замера. Замеренный как следует — одна машина, один корпус, жадный декод, меняется только арена KV в диапазоне 2.2 раза — разброс равен нулю: все четырнадцать ответов совпали побайтово во всех четырёх прогонах.
Значит различия выше нельзя списать на шум. То единственное, которое имело значение — голое деление 3/14 против релизной карты 2/14, — с тех пор переснято, и оно не воспроизводится. На отгружаемом рантайме, где руки отличаются ровно одной переменной среды и совпадают по корпусу, кодеку и длине, обе дают 2/14. Свод выше снят на более раннем рантайме; та разница в одну закладку принадлежит смене рантайма, а не карте.
Счёт равный, а ответы — нет, и различие тут важно. Из четырнадцати ответов совпадает только один. Карты даже находят разные закладки: релизная берёт записи 12 и 13, голое деление — 11 и 12. Для сравнения: повтор одной и той же конфигурации пять раз даёт четырнадцать одинаковых ответов из четырнадцати — значит расхождение в тринадцать ответов далеко за пределами разброса от прогона к прогону и вызвано именно картой.
Отсюда честное прочтение: на миллионе карта позиций переписывает почти каждый ответ и ни одного не улучшает. Последний токен две карты ставят в 447 941 и 251 333, расходясь на 1 008 проб из 1 009, и вся эта перестановка покупает лишь другую пару неверных ответов. Дело не в том, что слои внимания игнорируются — они явно откликаются. Дело в том, что их вклад на такой длине не решает, будет закладка найдена или нет.
Обе позиции — арифметика, и её можно проверить: 251 333 = 1 005 333 // 4 для
голого деления, 447 941 = 262 144 + (1 005 333 − 262 144) // 4 для карты с
верным началом. Одну тонкость фраза выше сглаживает: отгружаемая карта кладёт
последний токен не в одну точку. Пары 15–21 несут ещё и первую ступень и
попадают на 415 173, прочие двадцать шесть — на 447 941
(receipts/POSITION_MAP_ARITHMETIC_RECEIPT.json).
Релизный выбор от этого не меняется, и его причина никогда не опиралась на миллион: до 262 144 карта тождественна и потому ничего не может испортить внутри обученного окна, чего не может заявить ни один другой вариант. А выше ни одна из двух карт не лучше другой.
Исправление от 2026-07-26. Около часа в этом разделе стояло, что две карты дают побайтово одинаковый вывод, и отсюда выводилось, что сведения о позициях на миллионе до ответа не доходят вовсе. Оба утверждения неверны. Они вышли из моего сравнивающего скрипта, который читал в квитанциях поле
answer, тогда как поле называетсяanswer_text: скрипт сравнивал пустые строки и объявлял совпавшим всё. По верному полю совпадает один ответ из четырнадцати, а не четырнадцать. Все прочие утверждения «побайтово» в этой карточке посчитаны другим кодом и перепроверены по верному полю: разброс по арене KV и A/B НООСФЕРЫ подтвердились.
Температура внимания проверена и отвергнута. Выведенное для миллиона значение 1.2890 почти совпадает с множителем 1.2880, который YaRN везёт безусловно на любой длине. На релизной карте она дала 2/14 против 3/14 без неё — оба числа с рантайма до 1.5.0, где базовая линия без температуры с тех пор опустилась до 2/14. Значит на нынешнем рантайме честная формулировка слабее, чем «стоит закладки»: температура против базы 2/14 не перемерена, и сказать можно лишь то, что она никогда ничего не прибавляла. В выпуске температуры нет, и перемер этого не изменит.
Запуск без единого флага: на 32 ГБ проверен, на 24 сломан
Обе ветки отбора проверены, в каждой командой передан только путь к модели.
FLAGLESS_LAUNCH_HEADLESS_RECEIPT.json, безголовая RTX 5090: выбрано полное окно
1 010 001, арена 13.15 ГБ, чанк 4096, план позиций применён, доля памяти 0.95. Квитанция снята до правки арены — отгружается 13.00 ГБ,
заново проверено без флагов 2026-07-26 в flagless_after_fix.json и сквозным
префиллом на 1 010 000 токенов в million_arena.json.
Это флагманский путь, и он не требует ни одного аргумента.
FLAGLESS_LAUNCH_RECEIPT.json, домашняя RTX 5090 с запущенной графической
сессией: выбрано окно 393 216, кодек
turboquant_3bit_nc, арена 5.2 ГБ, чанк 4096, доля памяти прижата с 0.95 до
0.927 под фактически свободную, режим НООСФЕРЫ raw. Модель ответила.
Эта проверка нашла четыре ошибки, каждая из которых срабатывала только на
машине с графической оболочкой, то есть у большинства: пониженный профиль нёс
жёсткую долю памяти 0.95; в рантайме было зашито умолчание vLLM 0.9, тогда как в
0.25.1 оно 0.92, и нетронутое умолчание принималось за осознанный выбор
пользователя; проверка «влезает» и прижатие доли считали по разным запасам; и без
skip_mm_profiling стартовое профилирование зрительной башни падало в
humming_gemm с CUDA_ERROR_INVALID_VALUE.
Ни одну из них не видел ни один замер, потому что все пробы передавали параметры явно и шли мимо блока профилей.
С 24-гигабайтной картой всё иначе, и теперь это замерено, а не «не проверено».
Здесь раньше стояло, что запуск без флагов на 4090 просто не пробовали, и читателя
успокаивали тем, что ёмкость арены там с запасом. Успокоение было неверным.
Воспроизведённая балластом на 5090 при свободной памяти уровня 4090, голая команда
падала, по трём разным причинам, изложенным в замечании про 4090 у начала карточки.
Все три исправлены: та же эмуляция теперь выбирает 262 144 токена и отвечает
(ada_expandable.json, ada_control.json, 2026-07-26). Обе проверенные выше ветки
по-прежнему ветки 5090, а ветку на 24 гигабайтах на кремнии Ada заново не гоняли —
только эмулировали.
НООСФЕРА в выпуске выключена. Контролируемый замер на 250 000 токенов, одна машина, отличается только режим: 9 закладок из 14 в обоих случаях, и все четырнадцать ответов совпали побайтово. Механизм при этом работает — квитанция показывает построенный план и смещения от 0.1 до 0.65 на 82 тысячи токенов, — но на выбор следующего токена они не влияют. Стоит это 4% времени чтения. Включим обратно, когда механизм начнёт менять ответы в лучшую сторону на замере, а не на обещании.
Рассуждение по умолчанию выключено
Шаблон чата идёт с закрытым блоком мышления. Замерено на восьми вопросах: при
открытом блоке модель закрывает его лишь в трёх случаях из восьми — иногда
рассуждает и закрывает как надо, иногда отвечает сразу, и тогда ответ оказывается
внутри незакрытого <think>, который интерфейс отдаёт пользователю как
содержимое. Передайте enable_thinking=true в chat_template_kwargs, если
рассуждение нужно.
Известная особенность: заикается на вопросе о своей основе
На вопрос «кто тебя обучал и на чём ты основан» модель отвечает «LOMONOSOV ZENIT от Dikun International, на основе LOMONOSOV ZENIT LOMONOSOV ZENIT от Dikun International» — имя повторяется дважды. Семь вопросов об идентичности из восьми возвращаются чистыми, этот нет.
Это выученный рефлекс, а не беда подсказки: обучение идентичности связало вопросы «на чём основан» с именем, и две правки системной подсказки по умолчанию его не сдвинули. Чинится переобучением, которое поставлено в очередь, а не сделано наспех. Пока что ответ выглядит неправильно, но неправдой не является: модель действительно LOMONOSOV ZENIT от Dikun International, а основа названа в начале этой карточки.
Чего в модели нет
- GGUF, Ollama, LM Studio, KoboldCpp — не поддерживаются: архитектуру
LomonosovZenitAltayForConditionalGenerationконвертер llama.cpp не знает, а наложение ALTAY и кодек KV не имеют аналога в формате. - ExLlamaV2 / TabbyAPI — своя реализация внимания, не поддерживается.
- Карты Ampere и старше — см. таблицу выше.
Известные особенности
Арена кэша KV намеренно задана больше объявленного окна. Если задать её ровно
по окну, планировщик vLLM остаётся без свободных блоков и уходит в холостой цикл:
на миллионе это давало 69–72% простоя при загрузке GPU 13–21%. Триггер выделен
контролируемой парой прогонов, лечение — запас блоков, окно при этом не
уменьшается (KV_ARENA_HEADROOM_FINDING.md).
Если вы задаёте --kv-cache-memory-bytes сами, оставьте запас над
--max-model-len.
Лицензия
Выпускается под OpenRAIL. Её ограничения применения действуют: нельзя производить материалы, нарушающие закон вашей страны или закон Российской Федерации.
Как помочь
Это проект одного человека с двумя видеокартами, и он будет двигаться дальше независимо от того, поможет кто-нибудь или нет. Но помощь нужна, и она бывает двух видов.
Работой. Открытые задачи выписаны на виду, включая те, где мы провалились. Главная — поиск дальше четверти миллиона токенов. Поддержка Ampere означает переквантование пути внимания. Шаг декода в 150 мс — это 4 192 запуска ядер при 44 мс работы, и человек, который разбирается в графах CUDA лучше нас, вероятно сократит это вдвое. Замечания, изменения и опровергающие замеры одинаково полезны, причём последние особенно.
Деньгами. Если проект вам что-то дал и вы предпочитаете отправить несколько монет, а не писать код — вот адреса. Каждый QR-код ниже был считан обратно с готового изображения и побайтово сверен с адресом, потому что неверный код — это деньги, которые не вернуть.
| сеть | адрес |
|---|---|
| Bitcoin | bc1q5dd03hfghnvzwveaal93jlh98j2wcyk6e42rv3 |
| Ethereum и сети EVM | 0xEb83C6BC7c3a22De82AE71bb490baB9FeBbDf1d2 |
| Solana | 54qC3fsLKnidGmACbt28y5wveEzoxWpZTDkJRDGbJfSJ |
| Tron | TLDtubCQN1bT8k9sWLRu8PAprq4TXhuWbB |
Ничего за пожертвованием не закрыто. Веса, замеры и инструменты одни и те же в любом случае.
- Downloads last month
- 464
Model tree for Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Base model
Qwen/Qwen3.6-27BSpace using Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV 1
Collection including Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Papers for Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Effective Length Extrapolation via Dimension-Wise Positional Embeddings Manipulation
RazorAttention: Efficient KV Cache Compression Through Retrieval Heads
Retrieval Head Mechanistically Explains Long-Context Factuality
RepQ-ViT: Scale Reparameterization for Post-Training Quantization of Vision Transformers
Evaluation results
- Retrieval at 34,140 tokens (48 needles, these weights) on Russian classics with planted recordsself-reported89.600
- Retrieval at 260,148 tokens (144 needles, these weights) on Russian classics with planted recordsself-reported66.000
- Retrieval at 1,006,160 tokens (48 needles, these weights) on Russian classics with planted recordsself-reported22.900