Спойлер для экономии времени читающих — я просто скачаю DeepSeek и запущу его через llama.cpp, на какую-либо научную новизну этот пост совершенно не претендует. Зачем это на хабре, если там всего одна команда? Просто в комментариях к посту «Мануал по запуску полной модели DeepSeek-R1 локально» я спросил «имеет ли смысл попробовать на том железе, что у меня есть», и меня попросили это сделать, ну и некоторое количество «плюсиков» говорит о том, что кому-нибудь это будет интересно, ну а раз паззл сложился — о том и пост, просто развёрнутое продолжение, алаверды, так сказать, к предыдущему оратору. И да, я абсолютный дилетант в LLM, это первая «пристрелка», так что «туториалом» оформлять пост не буду, там могут быть неточности. Если кому интересны подробности — можно продолжить чтение.
Второй спойлер — да, это работает. Но очень медленно. Но работает.
Железо
Упражняться я буду вот на такой конфигурации:
HP z8 G4 рабочая станция примерно пятилетней давности в практически стоковом варианте.
Два процессора Xeon Gold 6132, 768 GB памяти DDR4, терабайтный NVMe SSD Samsung.
.
CPU-z выдаёт мне 10000+ попугаев:

Память набрана плашками по 64 ГБ, их там двенадцать штук:

Бенчмарк памяти и кэша я уже в комментах показывал, вынесу сюда тоже:

Видеокарт там две — NVidia Quadro K4200 да AMD Radeon Pro WX 9100, но использоваться как GPU они не будут (смысла в общем нет).

Диск:

Вообще их там четыре таких, но в рейд объединять не буду, модель один раз грузится в память, в принципе и так норм.
Комп остался как тестовый от одного проекта, в котором надо было быстро обрабатывать полтерабайта картинок, прилетающих от нескольких скоростных камер, теперь просто пылится под столом и эпизодически используется для упражнений.
Скачиваем DeepSeek
Я бы мог просто написать «скачайте DeepSeek R1 Q8_0», но тут есть небольшой нюанс. Дело в том, что на работе у меня все искусственные интеллекты старательно заблокированы злым админом, охраняющим интеллектуальную собственность. У меня нет онлайн доступа ни к ChatGPT, ни к Perplexity, ни к DeepSeek, равно как все дропбоксы, гуглодрайвы, онлайн заметочники — блокировано решительно всё. Причём не только на уровне прокси, но также фактически осуществляется MITM подменой сертификатов, поэтому скачать с Hugging Face/Unsloth AI я ничего не могу, получая отлуп 500. Издержки работы в большой компании. Обходить защиты — чревато, ибо Большой Брат неустанно бдит, так что качать я буду дома. А дома у меня всего-навсего 100 Мбит (хоть и оптоволокно), так что процесс не быстрый (планируйте как минимум сутки).
Поскольку репозиторий содержит несколько моделей, то я решил, что я самый умный, и слегка погуглив нашёл способ выдернуть через гит отдельную папку, а не всю репу.
Вот как-то так это делается через sparse-checkout:
git clone -n --depth=1 --filter=tree:0 https://huggingface.co/unsloth/DeepSeek-R1-GGUF
cd DeepSeek-R1-GGUF
git sparse-checkout set --no-cone /DeepSeek-R1-Q8_0
git checkout
Я включил старый комп с файлопомойкой, проверил там свободное место, выполнил команды выше, убедился, что информация пошла по проводам, и пошёл спать. Наутро я обнаружил, что туда прилетели обновления и он перезагрузился. Ну, бывает, я и забыл, что незадолго до этого поставил туда свежую Windows да не настроил как следует.
Лирическое отступление — если вы хотите временно отказаться от обновлений и возможных сопутствующих перезагрузок, то просто включите Metered connection (по-немецки Getaktete Verbindung) для сетевого адаптера, это самый наипростейший способ достичь бесконечного аптайма на компе, постоянно воткнутом в интернет.
Я это сделал, и выполнив команды второй раз, обнаружил, что «докачки» там нет и в помине, git начал качать с нуля (это видно в lfs кэше, там сначала файлы складываются во временную папку). Тут я вспомнил, что у меня валяется древний QNAP NAS, там есть качалка, но тут меня ждала другая засада — раз в сутки провайдер сбрасывает соединение, при этом NAS на это нервно реагировал, вываливал ошибку и начинал скачку снова. С торрентами он худо-бедно справлялся, а вот с https — нет. Я уже хотел было отказаться от затеи, но вы же понимаете — если я во всеуслышание напишу вот прямо здесь, что не смог скачать семьсот гиг, то надо мной будет ржать весь хабр, и я буду подвергнут публичному остракизму, так что пришлось расчехлить менеджер закачек, которым я не пользовался уже много лет.
Я это всё к тому, что если захотите скачать на слабом канале — заранее проверьте, что вы можете уверенно докачивать при обрыве соединения.
Ладно, хватит длинного вступления, короче — вот репозиторий DeepSeek-R1-GGUF, вот модель DeepSeek-R1-Q8_0, а под спойлером — прямые ссылки на список файлов, которые можно скормить любому менеджеру, я пользовался JDownloader 2.
DeepSeek-R1.Q8_0-000??-of-00015.gguf
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00001-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00002-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00003-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00004-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00005-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00006-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00007-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00008-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00009-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00010-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00011-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00012-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00013-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00014-of-00015.gguf?download=true
https://huggingface.co/unsloth/DeepSeek-R1-GGUF/resolve/main/DeepSeek-R1-Q8_0/DeepSeek-R1.Q8_0-00015-of-00015.gguf?download=true
Плюс использования менеджера ещё и в том, что днём я могу уменьшить скорость, чтобы не доставлять неудобств домашним, а ночью «открывать кран» на всю катушку.
Пока идёт скачивание, чтоб было не скучно — могу предложить загадку, как раз про это.
Во второй половине девяностых, мы, новоиспечённые выпускники физтеха, порой собирались вместе, распивали крепкие спиртные напитки и иногда смотрели фильмы на видеокассетах. В числе наиболее популярных был фильм, который мы, подрабатывающие программистами, ласково называли не иначе как «это наше кино, про эти, про ГИГАБАЙТЫ!» Угадайте, о каком фильме, выпущенном в середине девяностых, шла речь? Потом спросим у DeepSeek.
Как бы то ни было, через пару дней и ночей на терабайтном диске у меня лежали пятнадцать заветных GGUF файлов. Бережно неся их на работу, испытал странное ощущение — это что же, у меня в руках почти вся взвешенная квинтэссенция знаний человечества?! Мда...
Запускаем.
Вообще говоря существует несколько способов «запустить» DeepSeek локально — LM Studio, Ollama, llama.cpp и OpenVINO, часть из них я почерпнул из комментов, за что спасибо. Я попробовал навскидку все, но без фанатизма.
Самый наипростейший, вероятно — LM Studio. Актуальная версия на момент написания поста — 0.3.9. Я попробовал поставить дома, всё без проблем, как демка скачивается простенькая DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf на четыре с половиной гига, что позволяет запустить это дело даже на моём древнем ноуте (32 ГБ, проц. i7-4940MX). Я попробовал — даже работает, но очень медленно. Файлы моделей по умолчанию лежат в %USERPROFILE%\.lmstudio\models\lmstudio-community, там они в поддиректориях типа \DeepSeek-R1-Distill-Qwen-7B-GGUF.
Я закинул на диск инсталлятор, но вот на hp z8 прилетела и уселась птичка обломинго — «тестовая» Qwen 7B хоть и загружалась, но вываливалась в «неизвестную ошибку» после первого же промпта, а с таким трудом выкачанная Q8_0 отказалась загружаться вовсе, сославшись на нехватку ресурсов (выгрузку в GPU я отключил, не помогло). Дальше я мучить её пока не стал и отложил красивую игрушку в сторону.
Ollama в основном рассчитана на то, что скачивать модель вы будете через неё же (что невозможно в моём случае, а перекачивать дома всё ещё раз — тут уж извините),
Welcome to Ollama!
Run your first model:
ollama run llama3.2
PS C:\Windows\System32> ollama run deepseek-r1:1.5b
pulling manifest
pulling aabd4debf0c8... 100% ▕████████████████████████████████▏ 1.1 GB
pulling 369ca498f347... 100% ▕████████████████████████████████▏ 387 B
pulling 6e4c38e1172f... 100% ▕████████████████████████████████▏ 1.1 KB
verifying sha256 digest, writing manifest, success
>>> hi!
<think>
</think>
Hello! How can I assist you today? ?
так то оно работает, а вот как «подоткнуть» ей уже заранее скачанные файлы GGUF — тут чуть сложнее. То есть место-то где они должны лежать, я знаю: %USERPROFILE%\.ollama\models, но там модель надо кидать в папку \blobs, при этом переименовать файл в sha256-<хеш>, кроме того, надо добавить конфигурационный файл в \manifests\registry\.ollama.ai\library\deepseek-r1, в общем тут надо «приготовить» модель через
"ollama create DeepSeekR1 -f DeepSeek-R1.gguf", но перед этим вам придётся смержить все пятнадцать файлов вместе через "gguf-split --merge DeepSeek-R1.Q8_0-00001-of-00015.gguf DeepSeek-R1.gguf", и в общем ну его в топку такие упражнения.
А вот с llama.cpp всё получилось, и очень просто. Я было приготовился долго и нудно собирать это дело из исходников, но делать это не надо, там есть готовые сборки под Windows. Поскольку у меня железка на Xeon с поддержкой AVX512, вот эту версию я и скачал для начала.
Короче, тупо забрасываем файлы модели и содержимое архива с утилитами в одну папку (да прямо в корень диска F:\ в моём случае)

И запускаем
llama-cli.exe -m DeepSeek-R1.Q8_0-00001-of-00015.gguf -p "Hi!" -n 4096
Всё.
Все параметры командной строки (на английском, под спойлером). их там овердофига:
llama-cli.exe -h
example usage:
text generation: llama-cli.exe -m your_model.gguf -p "Hi!" -n 128
chat (conversation): llama-cli.exe -m your_model.gguf -p "Hello!" -cnv
----- common params -----
-h, --help, --usage print usage and exit
--version show version and build info
--verbose-prompt print a verbose prompt before generation (default: false)
-t, --threads N number of threads to use during generation (default: -1)
(env: LLAMA_ARG_THREADS)
-tb, --threads-batch N number of threads to use during batch and prompt processing (default:
same as --threads)
-C, --cpu-mask M CPU affinity mask: arbitrarily long hex. Complements cpu-range
(default: "")
-Cr, --cpu-range lo-hi range of CPUs for affinity. Complements --cpu-mask
--cpu-strict <0|1> use strict CPU placement (default: 0)
--prio N set process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime
(default: 0)
--poll <0...100> use polling level to wait for work (0 - no polling, default: 50)
-Cb, --cpu-mask-batch M CPU affinity mask: arbitrarily long hex. Complements cpu-range-batch
(default: same as --cpu-mask)
-Crb, --cpu-range-batch lo-hi ranges of CPUs for affinity. Complements --cpu-mask-batch
--cpu-strict-batch <0|1> use strict CPU placement (default: same as --cpu-strict)
--prio-batch N set process/thread priority : 0-normal, 1-medium, 2-high, 3-realtime
(default: 0)
--poll-batch <0|1> use polling to wait for work (default: same as --poll)
-c, --ctx-size N size of the prompt context (default: 4096, 0 = loaded from model)
(env: LLAMA_ARG_CTX_SIZE)
-n, --predict, --n-predict N number of tokens to predict (default: -1, -1 = infinity, -2 = until
context filled)
(env: LLAMA_ARG_N_PREDICT)
-b, --batch-size N logical maximum batch size (default: 2048)
(env: LLAMA_ARG_BATCH)
-ub, --ubatch-size N physical maximum batch size (default: 512)
(env: LLAMA_ARG_UBATCH)
--keep N number of tokens to keep from the initial prompt (default: 0, -1 =
all)
-fa, --flash-attn enable Flash Attention (default: disabled)
(env: LLAMA_ARG_FLASH_ATTN)
-p, --prompt PROMPT prompt to start generation with
if -cnv is set, this will be used as system prompt
--no-perf disable internal libllama performance timings (default: false)
(env: LLAMA_ARG_NO_PERF)
-f, --file FNAME a file containing the prompt (default: none)
-bf, --binary-file FNAME binary file containing the prompt (default: none)
-e, --escape process escapes sequences (\n, \r, \t, \', \", \\) (default: true)
--no-escape do not process escape sequences
--rope-scaling {none,linear,yarn} RoPE frequency scaling method, defaults to linear unless specified by
the model
(env: LLAMA_ARG_ROPE_SCALING_TYPE)
--rope-scale N RoPE context scaling factor, expands context by a factor of N
(env: LLAMA_ARG_ROPE_SCALE)
--rope-freq-base N RoPE base frequency, used by NTK-aware scaling (default: loaded from
model)
(env: LLAMA_ARG_ROPE_FREQ_BASE)
--rope-freq-scale N RoPE frequency scaling factor, expands context by a factor of 1/N
(env: LLAMA_ARG_ROPE_FREQ_SCALE)
--yarn-orig-ctx N YaRN: original context size of model (default: 0 = model training
context size)
(env: LLAMA_ARG_YARN_ORIG_CTX)
--yarn-ext-factor N YaRN: extrapolation mix factor (default: -1.0, 0.0 = full
interpolation)
(env: LLAMA_ARG_YARN_EXT_FACTOR)
--yarn-attn-factor N YaRN: scale sqrt(t) or attention magnitude (default: 1.0)
(env: LLAMA_ARG_YARN_ATTN_FACTOR)
--yarn-beta-slow N YaRN: high correction dim or alpha (default: 1.0)
(env: LLAMA_ARG_YARN_BETA_SLOW)
--yarn-beta-fast N YaRN: low correction dim or beta (default: 32.0)
(env: LLAMA_ARG_YARN_BETA_FAST)
-dkvc, --dump-kv-cache verbose print of the KV cache
-nkvo, --no-kv-offload disable KV offload
(env: LLAMA_ARG_NO_KV_OFFLOAD)
-ctk, --cache-type-k TYPE KV cache data type for K
allowed values: f32, f16, bf16, q8_0, q4_0, q4_1, iq4_nl, q5_0, q5_1
(default: f16)
(env: LLAMA_ARG_CACHE_TYPE_K)
-ctv, --cache-type-v TYPE KV cache data type for V
allowed values: f32, f16, bf16, q8_0, q4_0, q4_1, iq4_nl, q5_0, q5_1
(default: f16)
(env: LLAMA_ARG_CACHE_TYPE_V)
-dt, --defrag-thold N KV cache defragmentation threshold (default: 0.1, < 0 - disabled)
(env: LLAMA_ARG_DEFRAG_THOLD)
-np, --parallel N number of parallel sequences to decode (default: 1)
(env: LLAMA_ARG_N_PARALLEL)
--rpc SERVERS comma separated list of RPC servers
(env: LLAMA_ARG_RPC)
--mlock force system to keep model in RAM rather than swapping or compressing
(env: LLAMA_ARG_MLOCK)
--no-mmap do not memory-map model (slower load but may reduce pageouts if not
using mlock)
(env: LLAMA_ARG_NO_MMAP)
--numa TYPE attempt optimizations that help on some NUMA systems
- distribute: spread execution evenly over all nodes
- isolate: only spawn threads on CPUs on the node that execution
started on
- numactl: use the CPU map provided by numactl
if run without this previously, it is recommended to drop the system
page cache before using this
see https://github.com/ggerganov/llama.cpp/issues/1437
(env: LLAMA_ARG_NUMA)
-dev, --device <dev1,dev2,..> comma-separated list of devices to use for offloading (none = don't
offload)
use --list-devices to see a list of available devices
(env: LLAMA_ARG_DEVICE)
--list-devices print list of available devices and exit
-ngl, --gpu-layers, --n-gpu-layers N number of layers to store in VRAM
(env: LLAMA_ARG_N_GPU_LAYERS)
-sm, --split-mode {none,layer,row} how to split the model across multiple GPUs, one of:
- none: use one GPU only
- layer (default): split layers and KV across GPUs
- row: split rows across GPUs
(env: LLAMA_ARG_SPLIT_MODE)
-ts, --tensor-split N0,N1,N2,... fraction of the model to offload to each GPU, comma-separated list of
proportions, e.g. 3,1
(env: LLAMA_ARG_TENSOR_SPLIT)
-mg, --main-gpu INDEX the GPU to use for the model (with split-mode = none), or for
intermediate results and KV (with split-mode = row) (default: 0)
(env: LLAMA_ARG_MAIN_GPU)
--check-tensors check model tensor data for invalid values (default: false)
--override-kv KEY=TYPE:VALUE advanced option to override model metadata by key. may be specified
multiple times.
types: int, float, bool, str. example: --override-kv
tokenizer.ggml.add_bos_token=bool:false
--lora FNAME path to LoRA adapter (can be repeated to use multiple adapters)
--lora-scaled FNAME SCALE path to LoRA adapter with user defined scaling (can be repeated to use
multiple adapters)
--control-vector FNAME add a control vector
note: this argument can be repeated to add multiple control vectors
--control-vector-scaled FNAME SCALE add a control vector with user defined scaling SCALE
note: this argument can be repeated to add multiple scaled control
vectors
--control-vector-layer-range START END
layer range to apply the control vector(s) to, start and end inclusive
-m, --model FNAME model path (default: `models/$filename` with filename from `--hf-file`
or `--model-url` if set, otherwise models/7B/ggml-model-f16.gguf)
(env: LLAMA_ARG_MODEL)
-mu, --model-url MODEL_URL model download url (default: unused)
(env: LLAMA_ARG_MODEL_URL)
-hf, -hfr, --hf-repo <user>/<model>[:quant]
Hugging Face model repository; quant is optional, case-insensitive,
default to Q4_K_M, or falls back to the first file in the repo if
Q4_K_M doesn't exist.
example: unsloth/phi-4-GGUF:q4_k_m
(default: unused)
(env: LLAMA_ARG_HF_REPO)
-hfd, -hfrd, --hf-repo-draft <user>/<model>[:quant]
Same as --hf-repo, but for the draft model (default: unused)
(env: LLAMA_ARG_HFD_REPO)
-hff, --hf-file FILE Hugging Face model file. If specified, it will override the quant in
--hf-repo (default: unused)
(env: LLAMA_ARG_HF_FILE)
-hfv, -hfrv, --hf-repo-v <user>/<model>[:quant]
Hugging Face model repository for the vocoder model (default: unused)
(env: LLAMA_ARG_HF_REPO_V)
-hffv, --hf-file-v FILE Hugging Face model file for the vocoder model (default: unused)
(env: LLAMA_ARG_HF_FILE_V)
-hft, --hf-token TOKEN Hugging Face access token (default: value from HF_TOKEN environment
variable)
(env: HF_TOKEN)
--log-disable Log disable
--log-file FNAME Log to file
--log-colors Enable colored logging
(env: LLAMA_LOG_COLORS)
-v, --verbose, --log-verbose Set verbosity level to infinity (i.e. log all messages, useful for
debugging)
-lv, --verbosity, --log-verbosity N Set the verbosity threshold. Messages with a higher verbosity will be
ignored.
(env: LLAMA_LOG_VERBOSITY)
--log-prefix Enable prefx in log messages
(env: LLAMA_LOG_PREFIX)
--log-timestamps Enable timestamps in log messages
(env: LLAMA_LOG_TIMESTAMPS)
----- sampling params -----
--samplers SAMPLERS samplers that will be used for generation in the order, separated by
';'
(default: penalties;dry;top_k;typ_p;top_p;min_p;xtc;temperature)
-s, --seed SEED RNG seed (default: -1, use random seed for -1)
--sampling-seq, --sampler-seq SEQUENCE
simplified sequence for samplers that will be used (default: edkypmxt)
--ignore-eos ignore end of stream token and continue generating (implies
--logit-bias EOS-inf)
--temp N temperature (default: 0.8)
--top-k N top-k sampling (default: 40, 0 = disabled)
--top-p N top-p sampling (default: 0.9, 1.0 = disabled)
--min-p N min-p sampling (default: 0.1, 0.0 = disabled)
--xtc-probability N xtc probability (default: 0.0, 0.0 = disabled)
--xtc-threshold N xtc threshold (default: 0.1, 1.0 = disabled)
--typical N locally typical sampling, parameter p (default: 1.0, 1.0 = disabled)
--repeat-last-n N last n tokens to consider for penalize (default: 64, 0 = disabled, -1
= ctx_size)
--repeat-penalty N penalize repeat sequence of tokens (default: 1.0, 1.0 = disabled)
--presence-penalty N repeat alpha presence penalty (default: 0.0, 0.0 = disabled)
--frequency-penalty N repeat alpha frequency penalty (default: 0.0, 0.0 = disabled)
--dry-multiplier N set DRY sampling multiplier (default: 0.0, 0.0 = disabled)
--dry-base N set DRY sampling base value (default: 1.75)
--dry-allowed-length N set allowed length for DRY sampling (default: 2)
--dry-penalty-last-n N set DRY penalty for the last n tokens (default: -1, 0 = disable, -1 =
context size)
--dry-sequence-breaker STRING add sequence breaker for DRY sampling, clearing out default breakers
('\n', ':', '"', '*') in the process; use "none" to not use any
sequence breakers
--dynatemp-range N dynamic temperature range (default: 0.0, 0.0 = disabled)
--dynatemp-exp N dynamic temperature exponent (default: 1.0)
--mirostat N use Mirostat sampling.
Top K, Nucleus and Locally Typical samplers are ignored if used.
(default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0)
--mirostat-lr N Mirostat learning rate, parameter eta (default: 0.1)
--mirostat-ent N Mirostat target entropy, parameter tau (default: 5.0)
-l, --logit-bias TOKEN_ID(+/-)BIAS modifies the likelihood of token appearing in the completion,
i.e. `--logit-bias 15043+1` to increase likelihood of token ' Hello',
or `--logit-bias 15043-1` to decrease likelihood of token ' Hello'
--grammar GRAMMAR BNF-like grammar to constrain generations (see samples in grammars/
dir) (default: '')
--grammar-file FNAME file to read grammar from
-j, --json-schema SCHEMA JSON schema to constrain generations (https://json-schema.org/), e.g.
`{}` for any JSON object
For schemas w/ external $refs, use --grammar +
example/json_schema_to_grammar.py instead
----- example-specific params -----
--no-display-prompt don't print prompt at generation (default: false)
-co, --color colorise output to distinguish prompt and user input from generations
(default: false)
--no-context-shift disables context shift on inifinite text generation (default:
disabled)
(env: LLAMA_ARG_NO_CONTEXT_SHIFT)
-ptc, --print-token-count N print token count every N tokens (default: -1)
--prompt-cache FNAME file to cache prompt state for faster startup (default: none)
--prompt-cache-all if specified, saves user input and generations to cache as well
--prompt-cache-ro if specified, uses the prompt cache but does not update it
-r, --reverse-prompt PROMPT halt generation at PROMPT, return control in interactive mode
-sp, --special special tokens output enabled (default: false)
-cnv, --conversation run in conversation mode:
- does not print special tokens and suffix/prefix
- interactive mode is also enabled
(default: auto enabled if chat template is available)
-no-cnv, --no-conversation force disable conversation mode (default: false)
-i, --interactive run in interactive mode (default: false)
-if, --interactive-first run in interactive mode and wait for input right away (default: false)
-mli, --multiline-input allows you to write or paste multiple lines without ending each in '\'
--in-prefix-bos prefix BOS to user inputs, preceding the `--in-prefix` string
--in-prefix STRING string to prefix user inputs with (default: empty)
--in-suffix STRING string to suffix after user inputs with (default: empty)
--no-warmup skip warming up the model with an empty run
-gan, --grp-attn-n N group-attention factor (default: 1)
(env: LLAMA_ARG_GRP_ATTN_N)
-gaw, --grp-attn-w N group-attention width (default: 512)
(env: LLAMA_ARG_GRP_ATTN_W)
--jinja use jinja template for chat (default: disabled)
(env: LLAMA_ARG_JINJA)
--chat-template JINJA_TEMPLATE set custom jinja chat template (default: template taken from model's
metadata)
if suffix/prefix are specified, template will be disabled
only commonly used templates are accepted (unless --jinja is set
before this flag):
list of built-in templates:
chatglm3, chatglm4, chatml, command-r, deepseek, deepseek2, deepseek3,
exaone3, falcon3, gemma, gigachat, glmedge, granite, llama2,
llama2-sys, llama2-sys-bos, llama2-sys-strip, llama3, megrez, minicpm,
mistral-v1, mistral-v3, mistral-v3-tekken, mistral-v7, monarch,
openchat, orion, phi3, phi4, rwkv-world, vicuna, vicuna-orca, zephyr
(env: LLAMA_ARG_CHAT_TEMPLATE)
--chat-template-file JINJA_TEMPLATE_FILE
set custom jinja chat template file (default: template taken from
model's metadata)
if suffix/prefix are specified, template will be disabled
only commonly used templates are accepted (unless --jinja is set
before this flag):
list of built-in templates:
chatglm3, chatglm4, chatml, command-r, deepseek, deepseek2, deepseek3,
exaone3, falcon3, gemma, gigachat, glmedge, granite, llama2,
llama2-sys, llama2-sys-bos, llama2-sys-strip, llama3, megrez, minicpm,
mistral-v1, mistral-v3, mistral-v3-tekken, mistral-v7, monarch,
openchat, orion, phi3, phi4, rwkv-world, vicuna, vicuna-orca, zephyr
(env: LLAMA_ARG_CHAT_TEMPLATE_FILE)
--simple-io use basic IO for better compatibility in subprocesses and limited
consoles
example usage:
text generation: llama-cli.exe -m your_model.gguf -p "I believe the meaning of life is" -n 128
chat (conversation): llama-cli.exe -m your_model.gguf -p "You are a helpful assistant" -cnv
Первый момент, который я обнаружил — при предложенном параметре -n 256 вывод останавливался «на полуслове», не доходя до конца (это количество токенов — number of tokens to predict), я увеличил его до 4096 и процесс пошёл. Можно вообще не указывать, но есть риск того, что её поток сознания не остановится.
Если кому интересен полный лог старта, то вот:
llama-cli.exe -m DeepSeek-R1.Q8_0-00001-of-00015.gguf ...
Far Manager, version 3.0.6000.0 x64
Copyright © 1996-2000 Eugene Roshal, Copyright © 2000-2022 Far Group
F:>llama-cli.exe -m DeepSeek-R1.Q8_0-00001-of-00015.gguf -p "Hi!" -n 4096
build: 4628 (cde38332) with MSVC 19.42.34436.0 for x64
main: llama backend init
main: load the model and apply lora adapter, if any
llama_model_loader: additional 14 GGUFs metadata loaded.
llama_model_loader: loaded meta data with 48 key-value pairs and 1025 tensors from DeepSeek-R1.Q8_0-00001-of-00015.gguf (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv 0: general.architecture str
= deepseek2
llama_model_loader: - kv 1: general.type str
= model
llama_model_loader: - kv 2: general.name str
= DeepSeek R1 BF16
llama_model_loader: - kv 3: general.quantized_by str
= Unsloth
llama_model_loader: - kv 4: general.size_label str
= 256x20B
llama_model_loader: - kv 5: general.repo_url str
= https://huggingface.co/unsloth
llama_model_loader: - kv 6: deepseek2.block_count u32
= 61
llama_model_loader: - kv 7: deepseek2.context_length u32
= 163840
llama_model_loader: - kv 8: deepseek2.embedding_length u32
= 7168
llama_model_loader: - kv 9: deepseek2.feed_forward_length u32
= 18432
llama_model_loader: - kv 10: deepseek2.attention.head_count u32
= 128
llama_model_loader: - kv 11: deepseek2.attention.head_count_kv u32
= 128
llama_model_loader: - kv 12: deepseek2.rope.freq_base f32
= 10000.000000
llama_model_loader: - kv 13: deepseek2.attention.layer_norm_rms_epsilon f32
= 0.000001
llama_model_loader: - kv 14: deepseek2.expert_used_count u32
= 8
llama_model_loader: - kv 15: general.file_type u32
= 7
llama_model_loader: - kv 16: deepseek2.leading_dense_block_count u32
= 3
llama_model_loader: - kv 17: deepseek2.vocab_size u32
= 129280
llama_model_loader: - kv 18: deepseek2.attention.q_lora_rank u32
= 1536
llama_model_loader: - kv 19: deepseek2.attention.kv_lora_rank u32
= 512
llama_model_loader: - kv 20: deepseek2.attention.key_length u32
= 192
llama_model_loader: - kv 21: deepseek2.attention.value_length u32
= 128
llama_model_loader: - kv 22: deepseek2.expert_feed_forward_length u32
= 2048
llama_model_loader: - kv 23: deepseek2.expert_count u32
= 256
llama_model_loader: - kv 24: deepseek2.expert_shared_count u32
= 1
llama_model_loader: - kv 25: deepseek2.expert_weights_scale f32
= 2.500000
llama_model_loader: - kv 26: deepseek2.expert_weights_norm bool
= true
llama_model_loader: - kv 27: deepseek2.expert_gating_func u32
= 2
llama_model_loader: - kv 28: deepseek2.rope.dimension_count u32
= 64
llama_model_loader: - kv 29: deepseek2.rope.scaling.type str
= yarn
llama_model_loader: - kv 30: deepseek2.rope.scaling.factor f32
= 40.000000
llama_model_loader: - kv 31: deepseek2.rope.scaling.original_context_length u32
= 4096
llama_model_loader: - kv 32: deepseek2.rope.scaling.yarn_log_multiplier f32
= 0.100000
llama_model_loader: - kv 33: tokenizer.ggml.model str
= gpt2
llama_model_loader: - kv 34: tokenizer.ggml.pre str
= deepseek-v3
llama_model_loader: - kv 35: tokenizer.ggml.tokens arr[str,129280] = ["<|begin▁of▁sentence|>", "<�...
llama_model_loader: - kv 36: tokenizer.ggml.token_type arr[i32,129280] = [3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
llama_model_loader: - kv 37: tokenizer.ggml.merges arr[str,127741] = ["Ġ t", "Ġ a", "i n", "Ġ Ġ", "h e...
llama_model_loader: - kv 38: tokenizer.ggml.bos_token_id u32
= 0
llama_model_loader: - kv 39: tokenizer.ggml.eos_token_id u32
= 1
llama_model_loader: - kv 40: tokenizer.ggml.padding_token_id u32
= 128815
llama_model_loader: - kv 41: tokenizer.ggml.add_bos_token bool
= true
llama_model_loader: - kv 42: tokenizer.ggml.add_eos_token bool
= false
llama_model_loader: - kv 43: tokenizer.chat_template str
= {% if not add_generation_prompt is de...
llama_model_loader: - kv 44: general.quantization_version u32
= 2
llama_model_loader: - kv 45: split.no u16
= 0
llama_model_loader: - kv 46: split.count u16
= 15
llama_model_loader: - kv 47: split.tensors.count i32
= 1025
llama_model_loader: - type f32: 361 tensors
llama_model_loader: - type q8_0: 664 tensors
print_info: file format = GGUF V3 (latest)
print_info: file type = Q8_0
print_info: file size = 664.29 GiB (8.50 BPW)
load: special_eos_id is not in special_eog_ids - the tokenizer config may be incorrect load: special tokens cache size = 819
load: token to piece cache size = 0.8223 MB
print_info: arch = deepseek2
print_info: vocab_only = 0
print_info: n_ctx_train = 163840
print_info: n_embd = 7168
print_info: n_layer = 61
print_info: n_head = 128
print_info: n_head_kv = 128
print_info: n_rot = 64
print_info: n_swa = 0
print_info: n_embd_head_k = 192
print_info: n_embd_head_v = 128
print_info: n_gqa = 1
print_info: n_embd_k_gqa = 24576
print_info: n_embd_v_gqa = 16384
print_info: f_norm_eps = 0.0e+00
print_info: f_norm_rms_eps = 1.0e-06
print_info: f_clamp_kqv = 0.0e+00
print_info: f_max_alibi_bias = 0.0e+00
print_info: f_logit_scale = 0.0e+00
print_info: n_ff = 18432
print_info: n_expert = 256
print_info: n_expert_used = 8
print_info: causal attn = 1
print_info: pooling type = 0
print_info: rope type = 0
print_info: rope scaling = yarn
print_info: freq_base_train = 10000.0
print_info: freq_scale_train = 0.025
print_info: n_ctx_orig_yarn = 4096
print_info: rope_finetuned = unknown
print_info: ssm_d_conv = 0
print_info: ssm_d_inner = 0
print_info: ssm_d_state = 0
print_info: ssm_dt_rank = 0
print_info: ssm_dt_b_c_rms = 0
print_info: model type = 671B
print_info: model params = 671.03 B
print_info: general.name = DeepSeek R1 BF16
print_info: n_layer_dense_lead = 3
print_info: n_lora_q = 1536
print_info: n_lora_kv = 512
print_info: n_ff_exp = 2048
print_info: n_expert_shared = 1
print_info: expert_weights_scale = 2.5
print_info: expert_weights_norm = 1
print_info: expert_gating_func = sigmoid
print_info: rope_yarn_log_mul = 0.1000
print_info: vocab type = BPE
print_info: n_vocab = 129280
print_info: n_merges = 127741
print_info: BOS token = 0 '<|begin▁of▁sentence|>'
print_info: EOS token = 1 '<|end▁of▁sentence|>'
print_info: EOT token = 1 '<|end▁of▁sentence|>'
print_info: PAD token = 128815 '<|PAD▁TOKEN|>'
print_info: LF token = 201 'Ċ'
print_info: FIM PRE token = 128801 '<|fim▁begin|>'
print_info: FIM SUF token = 128800 '<|fim▁hole|>'
print_info: FIM MID token = 128802 '<|fim▁end|>'
print_info: EOG token = 1 '<|end▁of▁sentence|>'
print_info: max token length = 256
load_tensors: offloading 0 repeating layers to GPU
load_tensors: offloaded 0/62 layers to GPU
load_tensors: CPU_Mapped model buffer size = 45565.90 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 46661.11 MiB
load_tensors: CPU_Mapped model buffer size = 28077.60 MiB
llama_init_from_model: n_seq_max = 1
llama_init_from_model: n_ctx = 4096
llama_init_from_model: n_ctx_per_seq = 4096
llama_init_from_model: n_batch = 2048
llama_init_from_model: n_ubatch = 512
llama_init_from_model: flash_attn = 0
llama_init_from_model: freq_base = 10000.0
llama_init_from_model: freq_scale = 0.025
llama_init_from_model: n_ctx_per_seq (4096) < n_ctx_train (163840) -- the full capacity of the model will not be utilized
llama_kv_cache_init: kv_size = 4096, offload = 1, type_k = 'f16', type_v = 'f16', n_layer = 61, can_shift = 0
llama_kv_cache_init: CPU KV buffer size = 19520.00 MiB
llama_init_from_model: KV self size = 19520.00 MiB, K (f16): 11712.00 MiB, V (f16): 7808.00 MiB
llama_init_from_model: CPU output buffer size = 0.49 MiB
llama_init_from_model: CPU compute buffer size = 1186.01 MiB
llama_init_from_model: graph nodes = 5025
llama_init_from_model: graph splits = 1
common_init_from_params: KV cache shifting is not supported for this model, disabling KV cache shifting
common_init_from_params: setting dry_penalty_last_n to ctx_size = 4096
common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable)
main: llama threadpool init, n_threads = 28
main: chat template is available, enabling conversation mode (disable it with -no-cnv) main: chat template example:
You are a helpful assistant
<|User|>Hello<|Assistant|>Hi there<|end▁of▁sentence|><|User|>How are you?<|Ass
istant|>
system_info: n_threads = 28 (n_threads_batch = 28) / 28 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | AVX512 = 1 | LLAMAFILE = 1 | OPENMP = 1 | AARCH64_REPACK = 1 |
main: interactive mode on.
sampler seed: 526007933
sampler params:
repeat_last_n = 64, repeat_penalty = 1.000, frequency_penalty = 0.000, presence_penalty = 0.000
dry_multiplier = 0.000, dry_base = 1.750, dry_allowed_length = 2, dry_penalty_last_n = 4096
top_k = 40, top_p = 0.950, min_p = 0.050, xtc_probability = 0.000, xtc_threshold = 0.100, typical_p = 1.000, temp = 0.800
mirostat = 0, mirostat_lr = 0.100, mirostat_ent = 5.000
sampler chain: logits -> logit-bias -> penalties -> dry -> top-k -> typical -> top-p -> min-p -> xtc -> temp-ext -> dist
generate: n_ctx = 4096, n_batch = 2048, n_predict = 4096, n_keep = 1
== Running in interactive mode. ==
Press Ctrl+C to interject at any time.
Press Return to return control to the AI.
To return control without starting a new line, end your input with '/'.
If you want to submit another line, end your input with ''.
Hi!
«Работаем»
Ну вот прям «работой» это назвать сложно, потому что это всё отчаянно медленно.
Сразу после запуска модель целиком в память не грузится (точнее не «коммитится»), она как бы «догружается» при общении и количество занятой памяти растёт по мере работы, выходя на «плато» после двух-трёх промптов.
При первом «холодном» старте до появления приглашения проходит почти две минуты, дальше она радует нас примерно токеном в секунду.
Я смастерил такую вот несложную оснастку, показывающую загрузку памяти и процессора, ну и таймер до кучи, что б вы прочувствовали эту боль (я ещё вырезал примерно минуту, пока часть модели грузилась с диска в память, остальное оставлю в реальном времени как есть):

Как видите, память заполнилась примерно на треть после старта и чуть более чем наполовину после первого промпта.
Если вводить следующие вопросы, то модель будет догружаться. Нет смысла мучить вас медленным выводом, я буду снимать кадр в секунду, проигрывая гифку с примерно двадцатикратным ускорением. Попросим у неё Рунге-Кутта, хорошо видно, как она на ходу задействует семьсот гигабайт памяти почти под завязку:

Вот вывод «как есть»:
Can you please provide C code of Runge Kutta Method for (x-y)/(x+y)?
Hi, DeepSeek!
Hi! How can I assist you today?
Can you please provide C code of Runge Kutta Method for (x-y)/(x+y)?
Certainly! The Runge-Kutta method is a numerical technique used to solve ordinary differential equations (ODEs). For the differential equation dy/dx = (x - y)/(x + y), we can apply the 4th-order Runge-Kutta method (RK4). Here's a C code implementation:
#include <stdio.h>
#include <math.h>
// Define the differential equation dy/dx = (x - y)/(x + y)
double f(double x, double y) {
return (x - y) / (x + y);
}
// 4th-order Runge-Kutta method
void rungeKutta4(double x0, double y0, double h, double x_target) {
double x = x0;
double y = y0;
double k1, k2, k3, k4;
printf("Initial conditions: x = %lf, y = %lf\n", x, y);
while (x < x_target) {
if (x + h > x_target) {
h = x_target - x; // Adjust step to reach x_target exactly
}
k1 = h * f(x, y);
k2 = h * f(x + h/2, y + k1/2);
k3 = h * f(x + h/2, y + k2/2);
k4 = h * f(x + h, y + k3);
y = y + (k1 + 2*k2 + 2*k3 + k4)/6;
x = x + h;
printf("x = %lf, y = %lf\n", x, y);
}
}
int main() {
double x0 = 1.0; // Initial x
double y0 = 0.0; // Initial y
double h = 0.1; // Step size
double x_target = 2.0; // Target x value
rungeKutta4(x0, y0, h, x_target);
return 0;
}
Important Notes:
Initial Conditions: The current example uses
x0=1.0
,y0=0.0
, step sizeh=0.1
, and integrates up tox_target=2.0
. Adjust these values as needed.Division by Zero: The function
f(x,y)
will have a division by zero ifx + y = 0
. Ensure your initial conditions and step size avoid this scenario.Adaptive Step Size: For better accuracy, you might want to implement adaptive step size control, but this example uses a fixed step size for simplicity.
Output: The code prints the solution at each step. Modify the
printf
statements as needed for your use case.
Let me know if you need further clarification!
На всё про всё у неё ушло десять минут реального времени (проверку корректности решения оставим за кадром). Процессор, как видите, был занят чуть больше чем на половину. Тут надо заметить, что у меня был включён гипертрединг (ну или гиперпоточность), так что сегодня утром первым делом я его отключил и повторил эксперимент, и да, отключение НТ уверенно кладёт стрелку нашего спидометра на ограничитель, теперь все ядра активно заняты (кстати, конкретно этот hp вовсе не ревёт при этом как самолёт, идущий на взлёт, что приятно):

По скорости сильных изменений в производительности я не заметил, примерно тоже самое, токен в секунду или около того. Но гораздо интереснее тут другое. Шёл второй день экспериментов, я и пожелал модели доброго утра (я обычно вежливый, да, в том числе с ИИ). Она очень обрадовалась, просветлела (даже несмотря на то, что я ошибся в имени), и на мой стандартный вопрос про Рунге-Кутта пустилась в пространные размышления о смысле жизни на сорок минут (время в гифке выше).
И вот тут как раз возник тот «ага!» момент, о котором много где упоминали, когда модель выдаёт что-то типа "Wait, but the step function can be part of the loop. Alternatively, write a function that takes x, y, h, and returns the new y..."
Вообще я считаю, что выданная простыня вполне заслуживает того, чтобы быть приведённой полностью.
Очень много букв
Good morning, DeppSeek!
Okay, the user greeted me with "Good morning, DeppSeek!" Let me start by acknowledging their greeting and setting a friendly tone. Maybe I should respond with a cheerful good morning and ask how I can assist them today. Since they might need help with something specific, I should keep the response open-ended to encourage them to share their request. I'll make sure to keep it concise and welcoming.
Good morning! � How can I assist you today? Whether it's brainstorming ideas, solving
a problem, or just chatting, I'm here to help! Let me know what's on your mind. �
Please provide C code for Runge Kutta method for (x-y)/(x+y)
Okay, the user is asking for C code that implements the Runge-Kutta method for the differential equation given by (x - y)/(x + y). Let me start by recalling what the Runge-Kutta method is. The fourth-order Runge-Kutta (RK4) method is a numerical technique used to solve ordinary differential equations (ODEs) with a given initial condition. It's more accurate than Euler's method because it uses multiple intermediate steps to approximate the solution over each interval.
First, I need to confirm the ODE the user wants to solve. The function provided is (x - y)/(x + y). Typically, ODEs are expressed as dy/dx = f(x, y), so I'll assume that the differential equation here is dy/dx = (x - y)/(x + y). That makes sense.
Next, I should outline the RK4 method. The RK4 method computes the next value y_{n+1} using the current value y_n and the weighted average of four increments:
k1 = h * f(x_n, y_n)
k2 = h * f(x_n + h/2, y_n + k1/2)
k3 = h * f(x_n + h/2, y_n + k2/2)
k4 = h * f(x_n + h, y_n + k3)
Then, y_{n+1} = y_n + (k1 + 2k2 + 2k3 + k4)/6
So, in the C code, I'll need to implement this formula.
The user wants a C program. Let me structure the code step by step. The code should include the necessary headers, define the function f(x, y) corresponding to the ODE, and implement the RK4 step as a function. Then, in the main function, set the initial conditions, step size h, number of steps, and loop through each step to compute the solution.
Wait, initial conditions are needed. Since the user didn't specify them, I should choose a default initial value, say x0, y0, and a range for x. Let's assume the user wants to start at some x0 (like 0) with y0, and compute up to a certain point. But since the user didn't specify, perhaps the code should take initial values, step size, and number of steps as inputs or define them as constants. To make it simple, maybe hardcode initial x and y, step size h, and the number of steps. Then, in the code comments, mention that these can be adjusted.
Also, need to be cautious about division by zero in the function (x + y) could be zero. The code should handle cases where x + y is zero, but since the user hasn't specified error handling, perhaps just note that in the comments.
Let me outline the code:
Include standard headers (stdio.h, math.h if needed, but here maybe not necessary). 2. Define the function f(x, y) which returns (x - y)/(x + y).
Implement the RK4 step function that takes current x, y, step h, computes k1-k4, updates y.
In main, set initial x0, y0, h, number of steps.
Loop over the steps, compute each step, print x and y.
But let's test this with an example. Suppose initial x0 is 1, y0 is 1, h=0.1, and compute a few steps. Wait, but if x0=1 and y0=1, then x + y = 2, so the function is (1-1)/2 = 0. So the first step would compute k1 to k4 based on that. However, if x and y start at 0, the denominator is zero. So need to ensure the initial values don't cause division by zero. So perhaps in the code example, choose x0=1, y0=2, just to have a safe starting point.
Alternatively, ask the user for input. But since the user didn't specify, it's better to hardcode values and mention in comments to adjust them.
Another point: in the code, when computing x, since the ODE is dy/dx = f(x,y), each step advances x by h. So in the main loop, after each step, x increases by h.
Putting it all together:
The code will have:
Function definition for f(x, y)
A function to perform one RK4 step
Main function with loop
Wait, but the step function can be part of the loop. Alternatively, write a function that takes x, y, h, and returns the new y.
Yes, that's better. So:
double rungeKuttaStep(double x, double y, double h) {
compute k1, k2, k3, k4
return y + (k1 + 2*k2 + 2*k3 + k4)/6;
}
But since each k depends on evaluations at different points, need to compute them step by step.
So here's the step-by-step code:
#include <stdio.h>
double f(double x, double y) {
return (x - y) / (x + y);
}
void rungeKutta4(double *x, double *y, double h) {
double k1 = h * f(*x, *y);
double k2 = h * f(*x + h/2, *y + k1/2);
double k3 = h * f(*x + h/2, *y + k2/2);
double k4 = h * f(*x + h, *y + k3);
*y += (k1 + 2*k2 + 2*k3 + k4) / 6;
*x += h;
}
int main() {
double x0 = 1.0; // Initial x
double y0 = 2.0; // Initial y
double h = 0.1; // Step size
int steps = 10; // Number of steps
printf("Initial conditions: x = %f, y = %f\n", x0, y0);
printf("Step size: %f\n", h);
printf("Number of steps: %d\n\n", steps);
for (int i = 0; i < steps; i++) {
rungeKutta4(&x0, &y0, h);
printf("Step %d: x = %f, y = %f\n", i+1, x0, y0);
}
return 0;
}
Wait, no: in each call to rungeKutta4, x is incremented by h. But the loop in main is called steps times, so after each step, x increases by h. That's correct.
Wait, in the initial code, x0 starts at 1.0. Then, after the first call to rungeKutta4, x0 becomes 1.0 + h (since *x +=h). So the first step's x is 1.1, and the y is updated. That's correct.
But in RK4, when you compute k1, you use x_n, then k2 and k3 use x_n + h/2, and k4 uses x_n + h. Then, after all, x increments by h. So that's accurate.
Now, let's check if the function f is correctly implemented. Yes, (x - y)/(x + y).
But wait, the user wrote the differential equation as (x - y)/(x + y). So dy/dx = (x - y)/(x + y). The code correctly returns that.
Potential issues: division by zero when x + y is zero. But the example initial conditions x0=1.0 and y0=2.0 avoid that. The user may need to adjust initial conditions accordingly.
Also, the code prints after each step, showing x and y.
But the user might want to integrate over a specific interval. Let's see: if h=0.1 and steps=10, x goes from 1.0 to 1.0 + 10*0.1=2.0.
Yes. So the code as written is correct.
I should test this code to ensure there are no syntax errors. Let me see:
The function rungeKutta4 takes pointers to x and y, modifies them in place.
The main function loops steps times, each time calling the function and printing.
The f function is correctly defined.
Yes, this should compile and run.
However, in the main loop, the initial print is before the loop, so the initial x and y are printed, then the loop starts. But the first call to rungeKutta4 modifies x0 and y0 to the next step. Then, the first printed step is after the first update. So the first printed step is Step 1: x=1.1, y= updated value.
If the user wants to see the values at each step including the initial, maybe the code should print before updating. But in the code as written, the initial conditions are printed once, then the loop starts, updates, and prints the new x and y each time. So the output shows the progression from the initial step onwards. That's okay.
Alternatively, adjust the code to print after each step, which is what is done here.
I think this code should work. Therefore, the answer should include this code with explanations of the parameters and a note about potential division by zero.
Here's a C implementation of the 4th-order Runge-Kutta method for the differential equation dy/dx = (x - y)/(x + y):
#include <stdio.h>
// Define the differential equation dy/dx = (x - y)/(x + y)
double f(double x, double y) {
return (x - y)/(x + y);
}
// Performs one iteration of RK4 method
void rk4_step(double *x, double *y, double h) {
double k1 = h * f(*x, *y);
double k2 = h * f(*x + h/2, *y + k1/2);
double k3 = h * f(*x + h/2, *y + k2/2);
double k4 = h * f(*x + h, *y + k3);
*y += (k1 + 2*k2 + 2*k3 + k4)/6;
*x += h;
}
int main() {
// Initial conditions
double x0 = 1.0; // Initial x-value
double y0 = 0.5; // Initial y-value
double h = 0.1; // Step size
int steps = 10; // Number of steps
printf("Starting at: x = %.2f, y = %.2f\n", x0, y0);
printf("Step size: %.2f\n", h);
printf("Number of steps: %d\n\n", steps);
for(int i = 1; i <= steps; i++) {
rk4_step(&x0, &y0, h);
printf("Step %2d: x = %.3f, y = %.6f\n", i, x0, y0);
}
return 0;
}
Key components:
f(x, y)
- Implements the differential equationrk4_step()
- Performs one RK4 iteration-
main()
- Controls the simulation with parameters:Initial conditions (x0, y0)
Step size (h)
Number of steps
Notes:
Adjust
x0
,y0
,h
, andsteps
as neededBe cautious when x + y = 0 (potential division by zero)
Accuracy depends on step size h (smaller h = more precision)
Output shows x/y values at each step
To use this program:
Compile with any C compiler (e.g.,
gcc rk4.c -o rk4
)Run the executable
Modify initial values for different starting conditions
Would you like me to explain any part in more detail or modify specific aspects of the implementation?
Насколько этот опус лучше того, что был приведён выше, это уже другой вопрос, но разительным образом отличающийся ответ от предыдущего при почти идентичном промпте — это любопытный момент (параметры запуска я, ясное дело, никак не менял).
Кстати, о параметрах. Есть два режима запуска.
Первый вот такой, он называется "Text generation":
llama-cli.exe -m your_model.gguf -p "Hi!" -n 4096
А второй с ключом -cnv — "Сhat (conversation)"
llama-cli.exe -m your_model.gguf -p "Hello!" -cnv
Первый используется в том случае, если искуственный интеллект пишет за вас диссертацию, а второй — если он используется в качестве собеседника (чат-бота). При этом инструкция говорит, что модель должна быть «заточена» под этот режим. В принципе вы можете попросить её саму рассказать об отличиях, она напишет, что в Чат режиме можно использовать структурированные реплики с метками (например, [INST], <<SYS>>), останавливать её токенами конца диалога (например, </s>) и что то там ещё.
Я попробовал и так и сяк и основное отличие, которое заметил, это то, что объяснения в режиме «чат общения» сопровождаются готовыми формулами в TeX формате, выглядит это вот так, если я вставлю вывод прямо в редактор хабра:
Explanation:
Function
f
: Implements the differential equation
-
RK4 Method:
Takes initial conditions
(x0, y0)
, step sizeh
, and targetx_target
.-
Iteratively computes the next y using the RK4 formulas:
...
Вообще я верю, что если я попрошу переписать формулы в таком формате, она это по любому сделает, независимо от режима запуска, но просто вот такое наблюдение. Надо будет поэкспериментировать с другими моделями.
Ну а так — русский вроде знает:

Грамматику правит, альтернативы предлагает, историю общения помнит:

В стихах тоже может, по-немецки в том числе. Похоже, моя исходящая деловая корреспонденция станет несколько разнообразнее.
Короче у меня под столом завёлся личный секретарь, хоть и чутка тормознутый. Гугль, википедия, вольфрам математика, словарь, корректор в одном флаконе, да ещё и на разных языках. Если вы хотите его (или её) о чём-нибудь спросить — не стесняйтесь, задавайте вопросы в комментах, я с удовольствием передам ваши вопросы и опубликую ответы.
При завершении работы выдаёт статистику, около одного токена в секунду:
llama_perf_sampler_print: sampling time = 52.33 ms / 209 runs (0.25 ms per token, 3993.66 tokens per second)
llama_perf_context_print: load time = 89790.30 ms
llama_perf_context_print: prompt eval time = 87115.12 ms / 112 tokens (777.81 ms per token, 1.29 tokens per second)
llama_perf_context_print: eval time = 1883493.69 ms / 1777 runs (1059.93 ms per token, 0.94 tokens per second)
llama_perf_context_print: total time = 3136520.40 ms / 1889 tokens
Кому не нравится консоль, можно запустить и вот так:
llama-server.exe -m DeepSeek-R1.Q8_0-00001-of-00015.gguf --port 8082
Эта штука поднимет веб сервер (по умолчанию на порту 8080, но он у меня занят, так что 8082), будет красивее:

Плюс там в настройках можно кое-что подкрутить, например она может писать количество токенов в секунду в каждом ответе, но меня консоль в общем не смущает.
Производительность
Она, конечно удручает. Безусловно, более быстрая память типа DDR5 слегка улучшит ситуацию. В идеале надо иметь быструю GPU память, но пяток адаптеров типа NVIDIA H200, у которых по 141 ГБ памяти с пропускной способностью под пять терабайт в секунду сразу отправят нас в мир шестизначных ценников.
Что по этой конфигурации, то там можно ещё немного попытаться подкрутить в BIOS.
Некоторый потенцал, возможно, кроется в NUMA:

Пока что там не всё хорошо, но общественность этим уже озаботилась, на гитхабе висит открытый тикет — Feature Request: NUMA-aware MoE Expert Allocation for Improved Performanc #11333. Вообще когда мы упираемся в пропускную способность памяти — как отметили в комментах к изначальному посту с точки зрения эффективности не очень хорошо иметь два процессора, конкурирующих за общую память (хотя эффективная работа с двенадцатиканальной памятью на двухпроцессорной системе вкупе с NUMA — это отдельная тема, требующая дотошной проверки и бенчмарков).
По параметрам запуска я сильно не лазал, возможно там тоже что-то можно подкрутить.
Можно пересобрать всё из исходников и посмотреть, где проседает производительность и пройтись по «горячим точкам», да хоть тем же Intel VTune.
Но уже понятно, что сильно быстрее от этого не станет, и даже если раскочегарить всё вдвое-втрое, этого будет мало, надо раз этак в двадцать быстрее.
Некоторая надежда на OpenVINO, по идее там примерно вот так можно запуститься, если из Питона:
import openvino_genai
# will run the model on CPU, GPU, or NPU are possible options
pipe = openvino_genai.LLMPipeline("F:\<Тут Модель>", "CPU")
print(pipe.generate("The answer to life, the universe, and everything?", max_new_tokes =4096)
Но напрямую gguf не поддерживается, там конвертировать надо, пока не брался. Если кто-нибудь уже делал подход к этому снаряду — напишите, пожалуйста в комментах.
AVX-512 — тоже отдельная тема, бывает и так, что код, черезчур активно использующий эти инструкции, начинает притормаживать из-за того, что процессор снижает частоту (ему слишком много транзисторов одномоментно переключать бывает сложновато и он греется), кроме того разные компиляторы отличаются эффективностью кодогенерации, можно попробовать пересобрать, скажем Intel OneAPI.
Если брать не такие увесистые модели, то, конечно, всё работает резвее, но и «качество» вывода падает — для того же Рунге-Кутта описание алгоритма ещё выдаётся, а вот исходный код — уже нет (хотя есть «coder» модели, заточенные как раз под написание кода, надо будет попробовать).
Но в общем и целом впечатляет, это да.
А, совсем забыл,
ответ на загадку про фильм
Hello, DeepSeek!
Greetings! I'm DeepSeek-R1, an artificial intelligence assistant created by DeepSeek.
For comprehensive details about our models and products, we invite you to consult our official documentation.
Can you please suggest the title of the Movie from mid 90s about Gigabytes?
The movie you're thinking of from the mid-90s that involves gigabytes and hacking is likely "Hackers" (1995). It prominently features themes of computer hacking, data, and includes references to large amounts of data (gigabytes), though its portrayal of technology is stylized and not entirely accurate. Another possibility is "The Net" (1995), which revolves around cyber-threats and data manipulation. Both films capture the tech-centric paranoia of that era! Let me know if you'd like more details. �
No, I mean Movie about transferring large volumes of the data
Ah, got it! The mid-90s movie centered around transferring large volumes of data—specifically gigabytes—is "Sneakers" (1992). While it’s slightly earlier than the mid-90s, it’s often associated with that era and involves a team of security experts tasked with stealing a "black box" device capable of decrypting any system, which ties into data transmission and security. If you’re looking for something strictly mid-90s, "Johnny Mnemonic" (1995) features a protagonist who carries sensitive data (160GB!) in his brain implant, navigating a cyberpunk world to deliver it. Either could fit your description! �
Со второй попытки — бинго! Речь шла про киберпанковский «Джонни-мнемоник» c Киану Ривзом. Триста c лишним гигабайт, о которых там речь, казались нам чудовищным объёмом в то время. Времена меняются, прогресс идёт.
Всем добра!
Комментарии (115)
rogoz
06.02.2025 14:45Есть ещё всякие варианты типа Q4_0, может будут быстрее?
kryvichh
06.02.2025 14:45Я думаю, у автора был академический интерес, попробовать запустить полный вариант DeepSeek R1 на своём железе.
А так да, с практической точки зрения квантизации уровня Q6_K (551Гб) практически должны быть неотличимы от оригинала (713Гб). Q5_K_M, Q5_K_S - высокое качество, близкое к оригинальной модели (475Гб и 462Гб). Q4_K_M - хорошее качество для большинства применений (404Гб).
AndreyDmitriev Автор
06.02.2025 14:45Есть ещё всякие варианты типа Q4_0, может будут быстрее?
У меня нет под рукой других, кроме разве что DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf, что я в LM Studio скачал. Её размер 4.5 ГБ. Вот я прямо сейчас проверил — она на этой конфигурации стабильно выдаёт 10 токенов в секунду, с этим уже можно жить, да. Но она совершенно не в курсе специфических вещей, вот к примеру, если пользоваться ею как справочником:
Быстро, но неверно А вот 700ГБ DeepSeek-R1.Q8_0, и это более-менее правильный ответ:
Медленно, но верно rogoz
06.02.2025 14:45Как я понял, всё "мелкое" не имеет отношения к настоящему DeepSeek, это дообученные другие открытые сетки.
Так что только варианты на сотни гигов, только хардкор.
kekusprod
06.02.2025 14:45Только не дообученные, а сжатые (квантизацией) и/или урезанные(уменьшением количества параметров). И почему не имеют отношения, имеют конечно же, авторы оригинальных сеток вполне себе публикуют решения с меньшим количеством параметров, а вот квантизацией уже занимаются энтузиасты
Moog_Prodigy
06.02.2025 14:45Если под "мелким" подразумевать типа 70b и менее - то да, это дообученные другие сетки. Но есть и родная DS, переквантизированная - емнип, 137b ,вот там уже настоящий дипсик, разумеется квантизованный. Есть еще версии DS на 200 с лишним параметров. Кто лучше и качественней - вопрос открытый.
4external
06.02.2025 14:45а какова стоимость сервера + памяти на сегодняшний день? хочется сравнить с набором из Н200 и т.п.
AndreyDmitriev Автор
06.02.2025 14:45В продакшен пошли тачки помощнее, там был гигабайт DDR5 и процессоры порезвее. Около тридцати тысяч такой комп стоил.
Вот наскидку я только что набросал на сайте hp, так и есть:
xxxgoes
06.02.2025 14:45Это если рассматривать брендовые решения "под ключ". Если проблемы с финансами, но есть время и желание, то думаю можно изобрести терабайт RAM на более или менее свежей платформе за ~$7500. Если совсем нет денег и есть готовность терпеть более низкую производительность (вероятно раза в 2-3), то на 2011-3 можно втиснуться в $2000.
Речь про used комплектующие.
vvzvlad
06.02.2025 14:45Мы в мск 2х2697v4 и 768гб памяти покупали где-то по $1500. Интересно, сколько там будет токенов в секунду. Запустить, что ли.
Shado_vi
06.02.2025 14:45расценки на железо 2011-3:
процессор ~200$ (x2)(есть более дешёвые за менее 80$)
ram 64гб ~60$ (x4 ~200$-256гб)(планки на 128гб примерно в 2 раза дороже)
материнка с поддержкой 256гб ~80$
процессоры 2011-3 v4 поддерживают до ~1.5тб ram, но проблема с материнками.
дешевые материнки "из китайских подвалов" обещают макс. 256гб.
бренды же на бу можно найти например с поддержкой 512гб за 500$, соответственно более емкие материнки ещё дороже и рациональность сборки весьма сомнительна наверно(это я 1-2 года назад изучал, сейчас актуальность может быть другая).
теоретически при сильной квантификации deepseek-r1 влезает вроде в бюджетное железо.
robert_ayrapetyan
06.02.2025 14:45Почему-то вспомнился миф про "640k ought to be enough for anybody"..
subpchevp
06.02.2025 14:45научите, пожалуйста, как на локальной версии deep seek реализовать возможность работать с подгрузкой фотографий и pdf файлов в качестве контекста для текстовых промтов?
Moog_Prodigy
06.02.2025 14:45Никак. Там кроме самой модели еще другие модели подключаются (распознаваторы если по простому). Тот же OCR вроде отдельным модулем крутится. В принципе никто не мешает это все запилить и для локального использования, но пока нормального решения никто не сделал.
rPman
06.02.2025 14:45У deepseek есть старенькие 7b модельки vl
У qwen есть по лучше и новее до 72b 2.5vl
slonopotamus
06.02.2025 14:45Тут надо заметить, что у меня был включён гипертрединг (ну или гиперпоточность), так что сегодня утром первым делом я его отключил и повторил эксперимент, и да, отключение НТ уверенно кладёт стрелку нашего спидометра на ограничитель, теперь все ядра активно заняты
Было N ядер, из которых использовалось 0.55N. Выключили гипертрединг, ядер стало 0.5N, загрузка 100%. При этом по идее стало медленнее из-за нехватки 0.05N ядер, которые могли бы быть загружены работой. Я прально понимаю? И в чём тогда прикол выключать HT? Отдельный вопрос почему оно не параллелится на все N. Не удивлюсь что там где-нибудь в недрах используется get_physical_cores().
svkreml
06.02.2025 14:45Llama.cpp насколько я знаю по умолчанию если не указывать количество потоков в параметрах запуска так и делает, берет именно ядра, а не потоки
AndreyDmitriev Автор
06.02.2025 14:45Да, правильно. Я просто проверил, что без него загрузка стала 100%. Если бы она и при выключенном гипертрединге осталась в районе 50, то надо было бы внимательно смотреть откуда там ноги растут и почему идёт недогруз. Теперь его по идее надо включить обратно и провести тщательные замеры (так то я проверил производительность "на глаз".). И да, вполне возможно, что с его включением станет чуть лучше (я, кажется и видел 1.2 токена с ним и 1.1 без него, но "кажется" - не считается). А может ведь и так получиться, что программа допустим видит 28 физических ядер, но при создании потоков они все "сядут" на один 14-ядерный процессор (операционка, скорее всего такую глупость не сделает, а вот программа по ошибке вполне может), у которого 28 логических потоков, он будет из кожи вон лезть на своём гипертрединге, а второй будет просто простаивать, я и в этом случае увижу 50% (мой индикатор показывает среднее по всем логическим ядрам) но в этом случае выключение гипертрединга даст и стопроцентную загрузку и безусловный и заметный прирост. Там был, кажется ключ управления потоками в опциях, я завтра гляну, если время будет. Полная, "на всю катушку" загрузка на 56 потоков - тоже бывает по итогу медленнее, чем 28 потоков по чистым ядрам, я читал на реддите, что многие игры работают заметно быстрее именно при выключенном HT.
Shannon
06.02.2025 14:45И в чём тогда прикол выключать HT? Отдельный вопрос почему оно не параллелится на все N.
HT не добавляет физических ядер, а лишь позволяет использовать не занятые сейчас другой задачей блоки. Ускорение только за счет пред загрузки данных в свободные блоки пока ядро считает, например, AVX-блоки, но количество тактов не меняется, так как физическое ядро одно и тоже.
Инференс это задача для AVX блоков, поэтому другие блоки свободны для фотоной работы винды и браузера - но так как количество тактов не меняется, то для задачи инференса производительность не вырастет, а просядет, ведь такты ядра будут заняты другой работой. Поэтому с включенным HT загрузка 50% это и есть настоящая загрузка всего 100% процессора.
И загрузка будет показываться 60%, что воспринимается как +10% производительности, а на деле для инференса получится -5% производительности. Еще для однородной задачи, так как задача не раскладывается на логические потоки, не эффективно создаются очереди в конвейерах, и постоянное переключение может создать тормоза.
И тут даже в теории не получить +50% производительности, количество тактов не меняется, и даже если будет написано 100% загрузки, что создает ощущение +50% производительности, то это на деле будет просто i/o wait.
Сейчас интел вовсе отказался от HT в новом поколении процессоров, сказав что настоящие энергоэффективные ядра лучше, а AMD оставляет SMT, так как в некоторых бенчмарках там получается +18% прирост.Поэтому стандартный совет отключить HT и проверить ваш сценарий.
rPman
06.02.2025 14:45на тестах именно так и происходит, как только количество потоков превышает физическое количество ядер, скорость инференса проседает
AndreyDmitriev Автор
06.02.2025 14:45А, кстати, это легко продемонстрировать за утренним кофе.
Смотрите, я буду вычислять SHA256 в четыре потока, запуская это дело на четырёхядерном i7, и если я отдам распределение потоков на откуп операционке (точнее, LabVIEW и операционке), то загрузка восьми логических ядер будет выглядеть вот так (извините за немецкий скриншот):
"Рыхленько" так. А теперь следите за руками - я могу посадить мои потоки на первые четыре ядра:
И получу 280 MB/s, но тут фактически работают два физических ядра.
А теперь я раскидаю потоки вот так:
И получу уже 470 MB/s, потому что теперь я занял четыре физических ядра.
Во всех трёх случаях средняя загрузка процессора - чуть больше половины, а вот производительность приложения сильно разная.
Выключая гипертрединг, я не даю возможности приложению сесть на ядра неоптимальным образом, но в последнем случае видно, что сама операционка (и остальные процессы) перебралась на незанятые "гипертредированые" ядра, и если их не будет, то она будет использовать те, где крутятся мои потоки, так что с выключенным HT производительность в теории может просесть, хотя и не намного. Рецептов по оптимальному использованию гипертрединга тут в общем нет, надо просто пробовать и так и сяк.
slonopotamus
06.02.2025 14:45Ну что за манипуляции...
Где картинка с MiB/s для первого сценария? С чем мне ваши 470 MiB/s сравнивать?
Вы опять запустили нагрузку с get_physical_cores() потоками? Запустите нормально, с восемью потоками, а не четырьмя. Очевидно от HT не будет толку, если не давать ему работу.
AndreyDmitriev Автор
06.02.2025 14:45Нет, не манипуляции, просто я хотел ограничиться тривиальным случаем, когда запускается четыре потока, с явным назначением аффинити, и некоторые "заходят не туда", просто для иллюстрации.
Если же я буду запускать потоки без явного указания процессора (как обычно и делают), то будет так (скорость в МБ/с): 4 потока - 436; 5 потоков - 457; 6 потоков - 490; 7 потоков - 503. Также видно, как он чуть чуть частоту роняет под нагрузкой.
Восемь потоков я не тестировал, потому что уже семь дают мне 99% процентов загрузки и при запуске восьмого цикл, отображающий индикатор встаёт колом. Но не думаю, что там будет большая разница с семью. По хорошему конечно код надо показывать, там секретов нет, просто это на LabVIEW.
Скриншоты
4 5 6 7
Shannon
06.02.2025 14:45Некоторый потенцал, возможно, кроется в NUMA:
Попробуйте запустить с ключом
--numa distribute
. Еще попробуйте добавить-nkvo
И можете перейти на Q4_K_S, сэкономит почти в 2 раза памяти, а качество при этом просядет незаметно.Как минимум на идентичной с вашей конфигурацией получают ~2t/s. Эпики с 16 канальной ddr4 3200 на 2x EPYC 7543 с 403 гб/с - 4 t/s. На эпиках с 12-канальной ddr5 4800 выходит на малом контексте до 9 t/s на Q4_K_S.
Не знаю скажется ли это в вашем случае на скорость, так как у вас модель влезает в память и так, но можно еще попробовать взять экспериментальный динамический низкий квант. Качество UD-IQ1 сильно лучшем, чем просто IQ1, потому что UD-IQ1 сохраняет важные веса внимания на уровне Q4_K_M, а все остальные уже квантует через матрицу важности до IQ1, в итоге получается не плохой гибрид по качеству.
Динамические UD кванты запускают даже просто с nvme на скоростях от 0.5 t/s до 1 t/s. Но правда такие скорости только под линуксом.
Еще сейчас идет работа по добавлению в ktransformers возможности для архитектуры V3 выгружать активные веса на GPU, и так как активных весов всего 37B из 671B, то это в теории может ускорить вывод с помощью одной GPU сильнее, чем как сейчас это работает в llama.cpp. Следить за этим можно тут.
DarkTiger
06.02.2025 14:45Не знаю текущей ситуации с арендой, но на пару-тройку дней нельзя ли арендовать за сотню-другую баксов в датацентре физический сервак на 2x6328 с 768 гигами, чтобы поиграться и оценить, стоит ли оно того?
Moog_Prodigy
06.02.2025 14:45А смысл? Поиграться вы можете и с вебмордой DS забесплатно (их уже много кто раскатали из компаний у себя). Локальная модель она для того, чтобы никуда ничего не утекало + независимость от интернета.
DarkTiger
06.02.2025 14:45Смысл - оценить, оно того стоит или нет. Не вкладываясь серьезно в железо до принятия решения.
Ну а независимость от инета... ну так себе аргумент.Hardcoin
06.02.2025 14:45Суть вопроса в чём? Если вам не нужна локальная модель без интернета, значит не нужна, вам решать. Сервер конечно можно арендовать или вы сомневались?
DarkTiger
06.02.2025 14:45Суть вопроса - перед приличными вложениями в железо стоит задать себе вопрос «а оно мне надо в реальности в такой конфигурации?»
Ну вот не может человек себе позволить стандартный сервак за миллион домой, бывает (я уж не говорю, что он шумит прилично так). Дальше возникает вопрос оптимизации - а если я урежу память вдвое, а вместо 6328 поставлю 4314, с этим все еще можно будет работать? Или ждать ответа по 4 мин мне не катит? И так далее.
rPman
06.02.2025 14:45Добавьте 'себе в тесты' запуск модели не на одном мощном дорогом сервере а на кластере из недорогих, в т.ч. на десктопных (которые до 128гб ram очень даже дешево собрать), правда пока в основную ветку разработки не добавлена эта поддержка, а оригинальный репозитарий не развивается, не уверен что deepseek будет поддерживаться (llama405 работала).
rPman
06.02.2025 14:45Ага давно уже поддерживается, воспринимайте подключенные машины по сети как видеокарты, локальной же машине по уму достаточно KV-cache размещать (но веса все равно будут переданы по сети с диска)
DarkTiger
06.02.2025 14:45Хм, мне кажется, как человеку, ранее плотно работавшему с HPC, что сетевые тормоза в этом миникластере будут иметь критическое значение для производительности системы в целом. А на тех картах, что тормоза вносить не будут, каком-нибудь ConnectX-6, дешевую систему собрать не удастся по определению. Это ИМХО.
sergeym69
06.02.2025 14:45Можно еще запустить на кластере из нескольких компов, в каждом и которых можно установить несколько видеокарт. На github есть https://github.com/exo-explore/exo - AI кластер из компов
uzd
06.02.2025 14:45Я у себя запустил deepseek-r1:671b на базе 1xEPYC 7702.
Конфигурация памяти - 16 x 64GB, работает в 8-канальном режиме на частоте 2933 MT/s.
Моделька работает на скорости 3.5-4.0 t/s, без фризов и без подгрузки данных с диска в RAM, как было описано в статье. Общаться с ней вполне можно, кроме случаев, когда в промпт нужно закинуть большой кусок текста или километрового лог-файла - парсинг такого промпта перед началом рассуждений модели может занять десятки минут.
Для запуска использовал ollama на базе ubuntu server. Модель при первом же запросе сначала полностью загружалась в память, и только потом шла обработка моего промпта.
Теоретически, если запустить модель на более свежем железе (EPYC 9005 в 12-канальном режиме на частоте DDR5-6000), то скорость работы модельки может быть до 3 раз быстрее относительно моего конфига.
P.S. Возможно, что автор столкнулся с описанной проблемой из-за параметра а-ля "use_mmap=1", который вместо загрузки данных модели с диска в RAM просто делает маппинг файла в оперативную память, и дальнейшее обращение к данным в памяти требует чтения с диска.AndreyDmitriev Автор
06.02.2025 14:45Нет. нет, там судя по всему просто выделение памяти так реализовано. После того как всё загрузилось, память забита на 90% и обращений к диску не производится, это я проверил. А при изначальной загрузке модели она SSD грузит на 100%, да, это видно. Там в принципе исходники есть, можно посмотреть, как она модель грузит (хотя я пока туда не лазил).
riv9231
06.02.2025 14:45Там используется mmap: адресное просьранство файла мапится на виртуальное пространство оперативной памяти. По мере обращения к страницам памяти они подгружаются из файла. Если памяти хватает, это делается только один раз.
Shaman124
06.02.2025 14:45С какой скоростью на вашей сборке будет работать модель в размерности ~70B? Например, эта - https://huggingface.co/bartowski/calme-3.2-instruct-78b-GGUF Она сейчас в топе на хагинфейсе - https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard#
Интересно сравнить со своей сборкой на трех GPU Nvidia Tesla P40 24Gb. На моих GPU в версии Q4_K_M получается в районе 5 токенов/сек. Вот и думаю, нужны ли при таких раскладах GPU...? На более современные GPU пяти и шестизначные ценники за 1 шт., а EPYC 7702 вполне доступный вариант.
uzd
06.02.2025 14:45Для модели calme-3.2-instruct-78b-Q4_K_M на простых промптах я получил примерно такие цифры производительности через llama.cpp:
prompt eval time = 7981.25 ms / 98 tokens ( 81.44 ms per token, 12.28 tokens per second)
eval time = 148880.31 ms / 372 tokens ( 400.22 ms per token, 2.50 tokens per second)
total time = 156861.56 ms / 470 tokens
P.S. А в DeepSeek-R1 для обработки запроса активируются только 37B из 671B параметров - это особенность моделей MoE.
linktoheaven
06.02.2025 14:45Запустил calme-3.2-instruct-78b-GGUF 8_0 на epyc 9v74 (это такой oem 80/160 ядерный эпик c TDP 400 Wt) и 196 Gb 4800 памяти. Получил 3.3 t/s при --thread 150. В треде на реддите с Epyc 9374F и 384Gb R1 выдает 9 t/s. Так что сейчас буду смотреть как оптимизировать.
PeterFukuyama
06.02.2025 14:45Вообще я верю, что если я попрошу переписать формулы в таком формате, она это по любому сделает, независимо от режима запуска, но просто вот такое наблюдение. Надо будет поэкспериментировать с другими моделями.
Раcсчитай определитель матрицы \begin{pmatrix} 3 & 2 & 1 & 2 & 3 \\ 2 & 2 & 1 & 2 & 2 \\ 1 & 1 & 1 & 1 & 1 \\ 2 & 2 & 1 & 2 & 2 \\ 3 & 2 & 1 & 2 & 3 \end{pmatrix}.
Матрица, которую вы предоставили, имеет размерность (5 \times 5). Определитель квадратной матрицы можно вычислить с помощью различных методов, таких как разложение по строкам
или столбцам, но для больших матриц это может быть довольно сложным. Вместо этого мы можем использовать свойства определителя, чтобы упростить задачу.У вашей матрицы есть следующие строки:
Первая и пятая строки одинаковы.
Вторая и четвертая строки тоже одинаковы.
Определитель квадратной матрицы с двумя одинаковыми строками равен нулю. Это свойство следует из линейности определителя относительно строк (или столбцов). Если у вас есть две
одинаковые строки в матрице, то эта матрица является вырожденной, а её определитель равен нулю.Таким образом, определитель вашей матрицы:
[
\det \begin{pmatrix}
3 & 2 & 1 & 2 & 3 \\
2 & 2 & 1 & 2 & 2 \\
1 & 1 & 1 & 1 & 1 \\
2 & 2 & 1 & 2 & 2 \\
3 & 2 & 1 & 2 & 3
\end{pmatrix} = 0
]qwen2.5-coder:14b
ru4pae
06.02.2025 14:45Честно скажу, не изучал еще вопрос плотно. В двух словах.
Возможно ли локальной модели скормить набор специфичной различной документации и использовать её как локального ИИ помощника?
kryvichh
06.02.2025 14:45Если без дообучения, нужно использовать LLM с большим окном контекста. У оригинальной DeepSeek R3 довольно большое - 128K токенов.
jorisploski
06.02.2025 14:45Я себе дистиллят 4.5 гб ставил на (как я понял) чуть лучше ПК, чем ноутбук. Огорчился сильно китайским символам(
Ну и у меня появилось очень много теоретических вопросов, которые смогла объяснить оригинальная вэбверсия китайцев. С другой стороны непонятное прибавилось.
О чем речь - как я понимаю, чтобы генерировать ответ сетка сначала генерит английский, редко китайский варианты и потом поверх запиливает уже русский перевод (ну как я понял). В связи с этим вопрос о попытках каким-то образом раздербанить модель до какой-то определенной конфигурации - которая общается корректно на русском языке - становится невозможной.
При этом, в моем понимании, у нейросети нет какой-то специфичной информации для контекста и в случае подгрузки ВЭБверсии - все будет ок, но данные 100% утекут. В офлайн версии получается надо либо поднимать ещё как минимум 2-3 нейросети для прямой подгрузки рагов, либо дообучать создавая новый дата-сэт
Спросив про устройство ее памяти, мне сразу накидали про анонимность, а дальше про векторность, уровни внимания, весы и т.д. Что гробит надежды на возможно обрезки не нужной инфы у сети. (Я надеялся, что есть механизм кластеризации, по простому аналогии и они жёстко привязаны)
Так что изыскания автора крайне полезны, спасибо)
EdsCh
06.02.2025 14:45Да DeepSeek R1 можно крутить уже без видеокарт. Я тоже недавно делал тест на AMD https://www.reddit.com/r/DeepSeek/comments/1idhqdw/tested_deepseek_r1_671b_model_with_ollama_and_cpu/
Vrag
06.02.2025 14:45I've ran it on AMD EPYC 9454P With 1Tb of RAM in a virtual machine
Т.е. вы получили 8 t/s на железе примерно за$ 13K (800 мать на SP5, 2500 CPU, 8x1200 RAM + 200 за б/у корпус + БП)? Я не увидел, что у вас было занято меньше 512 памяти, т.е. стоимость железа будет около $8K.
А знатоки могут сказать сколько будет стоить набрать то же количество токенов ригами с самыми дешовыми доступными видеокартами? Я так понимаю тут не стоит задача получить в лоб 512Гб видеопамяти (тогда понятно как считать), т.е. какое-то "комбо" из условно DDR4 и видеокарт, которое даст те же 8 токенов?
Vrag
06.02.2025 14:45Я правильно понимаю, что на железе:
- могущем работать дома (т.е. не требующего стойки для размещения и отдельного подвала для изоляции от шума);
- и стоимостью до 1500$ (системник с 2x16Gb картами и производительным тихим охлаждением)
можно позволить себе запустить функционал условно "недоалисы", т.е. типа локальной обработки простых голосовых команд "включи свет во дворе" или "какая погода на улице?"; полчения на них голосовых ответов; ну и например простой аналитики видеопотоков с 4-8 видеокамер?Shado_vi
06.02.2025 14:45системы с 256гб ram начинаются от 500$ примерно
Vrag
06.02.2025 14:45Да, я видел выше. Только я так понимаю, что 256 от 500$ подразумевает использование дешовой серверной памяти, которая стит минимум за Gb именно в плашках по 32гб. Ну и нужно что-то очень многоканальное. Что приводит нас к серверной матери с 8 минимум слотами. Я так понимаю, если это не будет китайский монстр, то скорее всего речь про б/у серверную мать, которая имеет с огромной вероятностью формфактор, не позволяющий её поставить в сравнительно небольшой корпус (а скорее всего речь про серверное шасси). Что противоречит моему вопросу про "могущее работать дома".
Или вы имеете ввиду, что описанный мной уровень задач не требует видеоускорителей в принципе и достаточно какого-то железа с большим количество RAM?Shado_vi
06.02.2025 14:45можно брендовые собрать бу.
например бу материнки на 128 и 256 асуса и других брендов можно было встретить меньше 200$.
а если новое, то ценники... лучше арендовать.(для рф санкции сказываются на ценах)
размеры от полноценных ATX до mATX.
256 = 32 x8 или 64 x4.
xeon это не только сервера но и системы для рабочих станций.честно, был в думах о сборке системы на Ram и ответил не переключившись. т.е. не совсем том контексте.
Vrag
06.02.2025 14:45Про цены на новое не уверен, что есть большая разница. Выше есть тест 8 t/s на EPYC 9454P. Я посмотрел. Он стоит 2300 на ebay и 250К на авито.
Рабочих станций сильно меньше серверов, значит меньше вторички и сильно большая цена. Плюс по размеру рабочая станция по сути эквивалентна tower серверу. Но тут как говорится, было бы желание, наверное, можно и найти раб.станцию недорого и перепаковать в сильно более тихий корпус.Shado_vi
06.02.2025 14:45под ваши задачи некоторые используют одноплатники и мини-пк.
знакомый один занимался тем что уменьшал размеры материнок обрезая ненужно.
1-2 года назад на али можно было встретить как раз метеринки asus для рабочих станций для 2011-3 v3 v4 меньше чем за 15т.р.
Vrag
06.02.2025 14:45Я пропустил ключевое слово "ТОЛЬКО", отсутствие которого вкорне меняет суть вопроса:
можно позволить себе запустить ТОЛЬКО функционал условно "недоалисы",
Shado_vi
06.02.2025 14:45avx512 vs avx2
насколько сильно преимущество avx512?AndreyDmitriev Автор
06.02.2025 14:45Разница есть, в пользу AVX512, но она невелика. Я только что прогнал вот эти две сборки
avx2 выдала 0.9 токенов в секунду, а avx512 — 1.1. Цифры я списал с веб интерфейса:
SpencerTauRus
06.02.2025 14:45Круто, а тесты на качество ответов будут? Логические загадки, модерацию?
AndreyDmitriev Автор
06.02.2025 14:45Это в общем не входило в задачу, интерес был чисто "академический". Тестировать же лучше "полноценную" версию, которая chat.deepseek.com. Чуть выше в комментах я сравнил выдачу на довольно специфическом вопросе по сравнению с DeepSeek-R1-Distill-Qwen-7B-Q4_K_M, но там в общем результат ожидаем. Вы что-то специфическое хотели спросить? Я могу передать ей вопрос.
riv9231
06.02.2025 14:45А если парочку 3090 может уже и 2-3 токена будут? Или если пиедположить, что только 48GB - это 13% от всей модели и предположить, что только 13% слоёв будет усктрено, для простоты, бесконечно, т.е. ввчисляться будут за 0 вреиени, то всё ускорится на эти же 13%, получим не 1 токен, а 1.13 токенов, что печально.
Я читал, что внутри модели deepseek есть паралелно исполняемые части и последовательно исполняемые. Может быть, можно выгиузить на gpu наиболее нагруженных экспертов (там есть такие - универсальные эксперты с общими знаниями), то ускорение может быть и болле существенным
drVit
06.02.2025 14:45>Q8_0 отказалась загружаться вовсе, сославшись на нехватку ресурсов
Это связано с ошибкой работы с памятью posix_memalign в Электроне, на котором работает LM-studio. Решение такое: надо пересобрать Электрон с ключом "без posix_memalign" и подменить его в сборке. Или подождать, пока в новом Электроне или LMstudio авторы это не исправят сами.
Inan_Morgan_Sebynu
Прочитал всю статью - автору респект!
Правильно понял - что вся модель запускается только на процессорах? Если рассчитывать оптимальную бюджетную конфигурацию для запуска и постоянной работы подобной модели - на что стоит сделать акцент? Как я понял из статьи - рациональнее взять один процессор с большим числом ядер - а насчет озу - обязательно прям настолько много? Или условно можно обойтись например 128 гб? Кто-то пробовал на домашнем пк запускать deepseek?
janvarev
Коротко (от человека, занимающегося LLM со своим сервисом, чтоб не голословно)
- В идеале, вся модель должна помещаться в памяти GPU - тогда будет 10-20 токенов в секунду. Но домашних карт на 780 Гб GPU нет :)))
- Можно на CPU. Тогда вы достигнете около 1 токена в секунду (как автор статьи) ЕСЛИ у вас вся модель поместится в оперативную память (для маленьких моделей 7B будет быстрее - но это явно не про DeepSeek)
- Можно на CPU с подкачкой с диска, если не помещается в оперативную память, но это неюзабельно - обычно скорость становится около 0.1 токена в секунду или меньше.
Учитывайте, что простой ответ с размышлениями будет занимать около 1000 токенов - ну, можно сделать выводы.
AlexeevEugene
Всего -то надо установить gpustack, найти 18 компов в каждом по 2 видюхи AMD RX 7900 XTX. И за каких-то жалких 6 миллионов можно получить больше 5 токенов)
mukca
Пойти на этаж выше к соседу майнеру.. слыш видеокарточки есть? А если найду?
Tsimur_S
Вот тут писали про 5-6 токенов в секунду на CPU - https://threadreaderapp.com/thread/1884244369907278106.html Это преувеличение или тут есть разница какая-то в железе/llm/размере контекста?
AndreyDmitriev Автор
Ну там навскидку железо заметно посвежее, опять же у AMD EPYC на DDR5 если верить спекам пропускная способность памяти аж 480ГБ/с, а моя конфигурация и из двухсот не выбегает. Там параметры запуска ещё чуть другие - добавлены опции --temp 0.6 -no-cnv -c 16384 . Я только что попробовал - но нет, результат примерно тот же. Что есть, то есть, а вот AMD EPYC у меня нет, чтоб сравнить.
Tsimur_S
Да скорее всего дело в ddr5, + у него 12 каналов на проц а у вас 6. Вот тут еще наткнулся на информацию: https://www.reddit.com/r/LocalLLaMA/comments/1h3doy8/stream_triad_memory_bandwidth_benchmark_values/
если она верна то пара 9135 выдаст еще в два раза больше bandwidth правда и стоят они в два раза дороже. По 1500 за штуку.
fermentum
С памятью более-менее понятно. Интересно еще какая зависимость у скорости генерации от количества ядер CPU и от их индивидуальной производительности. Что лучше - мало быстрых ядер или много медленных?
mukca
у меня на платформе 190ГБ/сек, но виртуализация, да и думаю среду другую выбрать можно
janvarev
Сложно сказать, возможно, относительно топовое железо можно догнать до 5-6 токенов, но там много должно сложиться.
riky
разные модели запускаются. автор по ссылке запускает оригинальную fp8, а автор данной статьи квантованную в Q8.
Nengchak
Какую модель можете посоветовать для мозгов НПЦ? То есть например чтобы общался сам. (Отвечал более-менее в тему)? Достаточно ли самой простой?
molnij
"Зависит от". Пожалуй самые маленькие я бы все-таки не стал тревожить, но от 7-8B на английском получить "более менее в тему" будет норм. А на GPU так и real-time выдаст практически
Nengchak
Спасибо
almaz1c
Т.е. для шустрой работы требуется десяток карт Nvidia A100 x 80 Gb ?
ZirakZigil
Или одну dgx b200. Хватит и r1 запихнуть, и генератор картинок рядом. Ну и скорости будет побольше.
40kTons
О какого рода дисках идёт речь - HDD или SSD? Если SSD, то SATA3 или NVME? А если RAID 0 из SSD сделать? Должно быть побыстрее и относительно бюджетно, если не планируется очень много гонять (ибо износ)
xxxgoes
Речь про NVME SSD. Износа быть не должно. Это же не обучение, веса константны.
mukca
чем быстрее скрость тем лучше, но там пока ответа ждать будешь можно составится, а износ, ... почему все на ssd используя егов прикладных задачах трясутся за его ресурс? вы хоть один диск убили так что флеш исчерпал ресурс перезаписи??
40kTons
Опыт HDD говорит что они замедляются по мере износа. Т.е. незачем ждать полной смерти, достаточно дождаться момента когда субъективно "чёт медленно работает, надо новый купить". У SSD вроде нет такой проблемы, но есть другая - если умрёт, то быстро. Благодаря этому выработалось какое-то щадящее отношение к SSD
Troft
Запускал deepseek 20b на своем железе, Intel 10700kf, 32гб ддр4, все работает отлично, конечно модель глупенькая, но работает на отлично, в режиме чата ответ делает секунд за 10-20
fermentum
Вы запускали не ДС. В таком размере это Квен/Лама с надстройкой ДС.
falldown
Это дистиллят. То есть другая модель дообученная на дипсике. Типа, "продукт шоколадосодержащий". Шаблонные тесты проходит, но стоит чуть шагнуть в сторону, как начинается галлюцинирование.
mukca
Причем небольшие модели даже на компе с 8 гиговыми карточками и 16 ГБ озу крутятся достаточно быстро, и даже пользоватся можно. Просто поставил LM Studio и вперед
janvarev
Sun-ami
А если на CPU с подкачкой с десятка дисков, объединённых в RAID? Или то же на паре хороших игровых GPU?
janvarev
Любая подкачка с диска режет скорость ужасно; это я еще про SSD NVM говорю.
AndreyDmitriev Автор
Да, вся модель должна помещаться в памяти. При этом я замечу, что на тестовой тачке память двенадцатиканальная, вот, для сравнения бенчмарк с двухканальной — тут тоже Xeon, но даже если я добью её до 768 ГБ, то будет ну очень грустно, просто сравните пропускную способность там и тут:
Shado_vi
с вашего скрина:
у вас процессор умеет в 4 канальный режим, но там прямо написано что запущен в 2 канальном режиме. запустите в 4-х и получите значительный прирост скорости.
для сравнения старый процессор:
AndreyDmitriev Автор
О, спасибо, хорошее замечание. Я, кстати, попробовал DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf запустить там и тут, так вот на компе из обзора она даёт 10 токенов, а на том, что в комменте выше - семь (даже если Quad не включён), и если включить, то, возможно даже они сравняются. Так что скорость в общем не совсем пропорциональна пропускной способности памяти, скорость процессора тоже важна. Результат интересный, ядро W-2245 где-то раза в полтора быстрее старого 6132, но тут их всего 8, а там 28. Я б ожидал токенов этак 4-5, но нет, оно быстрее.
Вот сухой бенчмарк, тачка слева даёт десять токенов, а справа - семь:
Shado_vi
перевод DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf упрощенно на русский,
эта модель основанная на Qwen и доученная(Distill) на ответах от DeepSeek-R1
то есть DeepSeek-R1-Distill-Qwen-7B-Q4_K_M.gguf это по факту Qwen.
кроме памяти ещё важна производительность процессора на вычисления avx2 avx512.
вы вроде упоминали что пропускная способность ddr5 у вас при работе не использовалась, то есть существует где то узкое место в работе.
например где то в комментах упоминалось про каналы процессора,
у вас на Xeon 6132 это 6 каналов памяти. Но стоит 12 планок памяти, я не специалист но предполагаю что переключения между планками не бесплатно и сказываются на производительности.
not-allowed-here
наоборот при правильном подборе и корректной настройке можно даже добиться небольшого прироста производительности...
mukca
добивайте планками, будет 80 ГБ сек
у меня на этом сервер 170-190 где то, но все равно работате как черепаха.. возмоджно из за современных средст виртуализации или LM studio
Glamych
Да там вагон моделей под разное железо, но рассуждения по полчаса и косяки при ответе на кириллице руинят полностью все. Проще юзать на сайте, тем более есть десктопное приложение. Автор какой-то дичью зантмается. Погоня за попугаями. Это же не хэшрейт майнинга битка или эфира, дорого и глупо.
Rubilnik
Там в предисловии как раз таки автор написал, что это ответ на просьбу протестировать его конфигурацию из комментариев к другому посту. Спортивный интерес так сказать.
not-allowed-here
2x AMD EPYC 7662 + 16 плашек DDR4 по 64 GB + мат.плата с Ali лучше от supermicro + БП на 1600Вт ну и водянка для охлаждения....
это даст 5-6 токенов в секунду на DeepSeek..... но там еще крутить и крутить настройки + наверное всё таки надо брать квантизированную Версию на INT8 - на мой ограниченный взгляд существенной разницы не увидел - тут вот даже интересна методология которая позволила бы понять разницу.....
mukca
Имеено так, но запущенно из-за спортиного интереса, во время апдейта серверов. Большого практического смысла нет, так как ворочится как черепаха, да еще в виртуальной среде.
s1lv3r-f0x
У меня стоит ryzen 7 5700g, 32 гига оперативы и карточка бюджетная rx580 на 8 гигов, при таких характеристиках около 11 токенов в секунду, что в целом неплохо на самом то деле, но была бы карточка помощнее и на 12 гигов и выше то было бы сильно лучше