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": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoProcessor, AutoModelForSeq2SeqLM processor = AutoProcessor.from_pretrained("Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", trust_remote_code=True) model = AutoModelForSeq2SeqLM.from_pretrained("Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV", trust_remote_code=True, device_map="auto") messages = [ {"role": "user", "content": "Who are you?"}, ] 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
LOMONOSOV ZENIT 27B «ALTAY» — INDEV
A 26,895,998,464-parameter multimodal model with a 1,010,000-token context, built to run on one consumer graphics card.
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, W8/W4 for vision, INT8 for embeddings. The KV cache is three-bit TurboQuant, 12.5 KiB per token.
Languages: English, Russian, Ukrainian. Multimodal input is inherited from the base model.
The "model size" badge above says about 17B. Ignore it. Hugging Face counts
the elements in each tensor as they are stored, and the NVFP4 text weights are
four-bit, packed two to a byte in U8 tensors. There are 11.96 billion such
bytes, holding 23.9 billion parameters; add the 3.17 billion FP8 attention
weights, where one byte is one parameter, and you get the real figure of
26,895,998,464. The badge is halving the packed half. Nothing is missing from
the files: 2,503 tensors, every shard's header verified against its file length
after a round trip through the Hub.
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.05 GB — it was oversized by 237 MB against a window that needs 12.03 GiB. With no flags, no environment variable and nothing else on the card, the engine now selects 1,010,001, reserves a 1,020,234-token cache, is ready in 52.6 seconds and answers.
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. On 24 GB it currently does not — see the correction above — so give a
24 GB card an explicit --max-model-len until the profile requirements are
re-measured.
About the million on a 5090, honestly. Weights take 16.44 GiB — that is the engine's own figure at load, not the size of the files, which is 15.68 GiB — and the cache arena 12.15 GiB, together 28.59 GiB. The card reports 31.84 GiB and the engine sees 30.86 of it, so 2.27 GiB is left for working memory — measured, and measured tight: the same profile fails at 1.78 GiB. That was on a headless card. A desktop session holds around a gigabyte, and then the million does not fit: the model steps down on its own, which is the designed behaviour, but do not expect the full window while working at the same machine. Close the graphical session, or give the display a second card.
Installing
pip install vllm==0.25.1
pip install <model directory>
vllm serve <model directory>
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).
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: 16.44 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.
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 | 52 s | 2496 |
| 262,144 | 146 s | 1799 |
| 524,288 | 460 s (7.7 min) | 1140 |
| 1,010,000 | 26 min | 648 |
RTX 4090: 32,768 tokens in 38 s (861 tok/s).
The slowdown with length is attention's quadratic cost rather than an implementation flaw: 460 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×: at a million tokens the next question takes 7.5 s instead of 26 minutes. So load the document once per session and ask as many questions as you like.
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 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.
| context | needles | prose (strict / by lexeme) |
|---|---|---|
| 33,334 | 92.9% (13/14) | 76.9% / 76.9% (10/13) |
| 250,334 | 92.9% (13/14) | 16.7% / 16.7% (2/12) |
| 1,005,334 | 14.3% (2/14) | 7.7% (13 q) |
The middle of this curve moved on 2026-07-26, and it moved a long way. The 250,000 row said 78.6%. On the shipped configuration it is now 92.9% — the same as at 33,334. Retrieval is flat from thirty-three thousand tokens to a quarter of a million.
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.
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.18 GB | works headless on a 5090 |
long_393k |
393,216 | 25.57 GB | threshold measured to 199 MB |
long_262k |
262,144 | 23.97 GB | threshold measured to 510 MB |
These two 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 16.44 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 the one figure here inherited from the estimate, and
it stays that way for a reason worth stating. A ladder forced the profile at three
memory levels and it failed at all three — but under the real config it would not
have been offered at any of them, so those failures say nothing. The band where
the declared value could actually be wrong is 304 MB wide, and our ballast holds a
CUDA context larger than that band. The instrument cannot measure this profile;
it consumes the very headroom under test. The declared value is therefore not
shown to be wrong, and we are not going to invent a better one.
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.
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.
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 fails, for three separate reasons set out in the 4090 note near the top of this card. Both branches verified above are 5090 branches; the 24 GB branch does not work yet.
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
Мультимодальная модель на 26 895 998 464 параметра с контекстом 1 010 000 токенов, рассчитанная на одну потребительскую видеокарту.
Это работа в процессе, и карточка говорит об этом там, где это важно. Каждое число ниже измерено на нашем железе и имеет квитанцию. Ничего не оценено на глаз, не экстраполировано и не округлено в свою пользу. Там, где что-то не работает, это написано так же прямо, как и то, что работает.
Что это
Гибридная архитектура: 48 слоёв гейтированного дельта-правила с состоянием фиксированного размера и 16 слоёв полного внимания, GQA — 24 головы запроса на 4 головы KV, размерность головы 256. Наложение ALTAY-72M-SKV: 72 логических слоя поверх 64 физических блоков KV. Веса: текст NVFP4, внимание FP8, зрение W8/W4, эмбеддинги INT8. Кэш KV трёхбитный TurboQuant, 12.5 КиБ на токен.
Языки: английский, русский, украинский. Мультимодальный вход унаследован от базовой модели.
Бейдж «model size» наверху показывает около 17B. Не верьте ему. Hugging Face
считает элементы тензоров так, как они лежат в файле, а текстовые веса в NVFP4
четырёхбитные и упакованы по два значения в байт, тип U8. Таких байтов 11.96
миллиарда, а параметров в них 23.9 миллиарда; прибавьте 3.17 миллиарда весов
внимания в FP8, где байт равен параметру, и получите настоящее число —
26 895 998 464. Бейдж делит упакованную половину надвое. В файлах ничего не
пропало: 2 503 тензора, у каждого шарда заголовок сверен с длиной файла после
скачивания обратно с Hub.
Построена на 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.05 ГБ — она была завышена на 237 МБ против окна, которому нужно 12.03 ГиБ. Без флагов, без переменной и без чего-либо ещё на карте движок теперь выбирает 1 010 001, отводит кэш на 1 020 234 токена, готов за 52.6 секунды и отвечает.
Все квитанции, названные в карточке поимённо, лежат вместе с моделью — в
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 гигабайтах сейчас не работает, см. исправление выше, поэтому
задавайте 24-гигабайтной карте явный --max-model-len, пока требования
профилей не переснимут.
Про миллион на 5090 честно. Веса занимают 16.44 ГиБ — это цифра самого движка при загрузке, а не размер файлов, который 15.68 ГиБ, — арена кэша 12.25 ГиБ, вместе 28.59 ГиБ. Карта сообщает 31.84 ГиБ, движку достаётся 30.86 из них, и на рабочую память остаётся 2.27 ГиБ — замерено, и замерено впритык: тот же профиль отказывает при 1.78. Замер сделан на безголовой карте. Графическая сессия держит около гигабайта, и тогда миллион не влезает: модель шагает вниз сама, это и есть задуманное поведение, — но рассчитывать на полное окно, работая за той же машиной, не стоит. Закройте графическую сессию или отдайте дисплею вторую карту.
Установка
pip install vllm==0.25.1
pip install <каталог модели>
vllm serve <каталог модели>
Патченный vLLM не нужен: бэкенд TurboQuant едет в публичном колесе, шесть файлов
совпали по sha256 между двумя независимыми установками
(STOCK_VLLM_BACKEND_RECEIPT).
На прогретой машине движок готов примерно за 53 секунды — медиана по 86 записанным запускам, основной разброс от 49 до 77 секунд. Из них чтение весов занимает 4.4 секунды: 16.44 ГиБ на скорости около 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 | 52 с | 2496 |
| 262 144 | 146 с | 1799 |
| 524 288 | 460 с (7.7 мин) | 1140 |
| 1 010 000 | 26 мин | 648 |
RTX 4090: 32 768 токенов за 38 с (861 т/с).
Спад с ростом контекста — квадратичная стоимость внимания, а не изъян реализации: 460 с на 524 288 токенах быстрее чистой квадратичной экстраполяции от 262 144.
Второй вопрос по тому же тексту почти бесплатен. Кэш префикса даёт 16.9× / 52.9× / 172.9×: на миллионе следующий вопрос — 7.5 с вместо 26 минут. Загружайте документ один раз за сессию и задавайте подряд сколько нужно вопросов.
Скорость генерации
Около 150 мс на токен, то есть примерно 6–7 токенов в секунду, почти независимо от длины контекста (8К — 154 мс, 131К — 169 мс). Это медленно, и причина известна: за один шаг запускается 4 192 ядра GPU при 44 мс собственно работы, то есть карта большую часть шага ждёт хост. Трёхбитный кодек KV стоит 36% шага: на fp8 шаг занимает 107 мс.
Мы это не скрываем и не выдаём за оптимум. Модель имеет смысл там, где важно прочитать много, а не быстро наговорить.
Графы CUDA выключены осознанно: замер дал 282 мс против 180 при их включении. Профиль шага с этим спорит, и перепроверка стоит в плане.
Удержание контекста
Мерялось на настоящей русской прозе двумя независимыми инструментами. Оба проверены на коротком контексте прежде, чем применяться к длинному.
Закладки. В прозу на известных глубинах вставлены четырнадцать записей вида «Особая заметка номер 7: код доступа к архиву — ЯНТАРЬ-6421», и по каждой задан вопрос. Ответа нет больше нигде в тексте, так что угадать нельзя.
Чтение прозы. Вопросы строятся механически из самого текста книги: берётся фраза с одним затёртым редким словом. Каждый вопрос сначала задаётся без книги, и то, на что модель отвечает по памяти о классике, из зачёта исключается.
| контекст | закладки | чтение прозы (строго / по лексемам) |
|---|---|---|
| 33 334 | 92.9% (13/14) | 76.9% / 76.9% (10/13) |
| 250 334 | 92.9% (13/14) | 16.7% / 16.7% (2/12) |
| 1 005 334 | 14.3% (2/14) | 7.7% (13 вопр.) |
Середина этой кривой сдвинулась 2026-07-26, и сдвинулась далеко. В строке 250 000 стояло 78.6%. На отгружаемой конфигурации теперь 92.9% — столько же, сколько на 33 334. Поиск ровный от тридцати трёх тысяч токенов до четверти миллиона.
Изменилась одна строка плана позиций. Пары частот, совершающие от одного до тридцати двух оборотов на обученном окне — пары 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 самая медленная пара не проходит и трёх
процентов оборота на всём миллионе, то есть сжимать там нечего.
Поэтому выпуск идёт на родных позициях, а окна шире обученного получают позиции иначе — см. ниже.
Профили запуска
Модель везёт параметры запуска в собственном config.json. Порядок выбора:
- переменная
ZENIT_SERVING_PROFILE; - явный
--max-model-len— берётся наименьший профиль, который его вмещает; - иначе самый широкий профиль, влезающий в фактически свободную память (проба через NVML, без создания контекста CUDA);
- иначе профиль по умолчанию.
Любое значение, заданное вами в командной строке, всегда сильнее профиля, и каждая подстановка пишется в лог.
| профиль | окно | требуется свободной памяти | замер |
|---|---|---|---|
raw_1010k |
1 010 001 | 32.18 ГБ | работает на безголовой 5090 |
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 не подходит ни один профиль, и лог говорит об этом поимённо и с цифрами, прежде чем остановиться. Последний случай правильный, а не сломанный: одни веса занимают 16.44 ГиБ, и карта с 21 ГиБ свободных не поднимет эту модель ни при каком окне.
У long_262k теперь есть и явная gpu_memory_utilization. Без неё прижимать было
нечего, и умолчание vLLM 0.92 просило больше, чем есть на тесной карте. Обе правки
нужны вместе — каждая по отдельности замерена и не работает.
Требование raw_1010k — единственное число здесь, доставшееся от оценки, и
остаётся им по причине, которую стоит назвать. Лестница форсировала профиль на трёх
уровнях памяти, и он отказал на всех трёх — но при рабочем конфиге он там не был бы
и предложен, так что эти отказы ни о чём не говорят. Полоса, где объявленное
значение действительно могло бы быть неверным, шириной 304 МБ, а наш балласт держит
контекст CUDA больше этой полосы. Инструмент не может измерить этот профиль: он
съедает ровно тот запас, который проверяет. Значит объявленное значение не
показано неверным, и выдумывать вместо него другое мы не станем.
План позиций везёт каждый профиль, и с 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, и вся эта перестановка покупает лишь другую пару неверных ответов. Дело не в том, что слои внимания игнорируются — они явно откликаются. Дело в том, что их вклад на такой длине не решает, будет закладка найдена или нет.
Релизный выбор от этого не меняется, и его причина никогда не опиралась на миллион: до 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.
Это флагманский путь, и он не требует ни одного аргумента.
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 у начала карточки. Обе проверенные выше ветки — это ветки 5090; ветка на 24 гигабайтах пока не работает.
НООСФЕРА в выпуске выключена. Контролируемый замер на 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
- -
Model tree for Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Base model
Qwen/Qwen3.6-27BPaper for Ddavidich/LOMONOSOV-ZENIT-27B-1M-INDEV
Evaluation results
- Retrieval at 33,334 tokens on Russian classics with 14 planted recordsself-reported92.900
- Retrieval at 250,334 tokens on Russian classics with 14 planted recordsself-reported92.900
- Retrieval at 1,005,334 tokens on Russian classics with 14 planted recordsself-reported14.300
- Strict at 33,334 tokens on Russian classics, one rare word blankedself-reported76.900
- Strict at 250,334 tokens on Russian classics, one rare word blankedself-reported16.700
- Strict at 1,005,334 tokens on Russian classics, one rare word blankedself-reported7.700