Comments 24
stablediffusion вполне работает на одном CPU без GPU
Оно оказалось не таким простым, как llama.cpp.
А на Эльбрусе вообще не собралось :(
Но там вопрос не к объему памяти, а в оптимизациях. Поэтому SD будет на телефоне работать быстрее.
Мне кажется, уважаемый автор спрашивал вообще о возможности запуска каких-либо text-to-image моделей, а не о том, какие из них лучше работают где. Понятно, что на условной 4090 оно будет работать еще лучше, да какой от этого автору прок?
StableDiffusion вполне таки чувствителен к объёму свободной памяти. Я когда я кручу stable-diffusion-ui (https://github.com/AUTOMATIC1111/stable-diffusion-webui) на домашней машине, то наблюдаю, как с моделью 1.4, при совершенно стандартных-из-коробки-настройках для CPU ...
cd <stable-diffusion-ui>
source venv/bin/activate
python launch.py --precision full --no-half --skip-torch-cuda-test
... на старте главный процесс отжирает 6 Гб + при инференсе еще до гигабайта.
Как ориентир, генерация одного изображения 512x512 на простом промпте ("man on a moon") занимает ~ 4 минуты на 4 потоках Ryzen 5 3400G. Мои попытки использовать ROCm, чтобы задействовать возможности встроенного графического ядра в моём Ryzen ни к каким значимым успехам не привели, кроме повышенных объёмов потребляемой памяти. Но готов поверить, что плохо и мало копал.
Попытки воспользоваться какими-то более продвинутыми функциями, типа img2img вообще крашатся по недостатку памяти.
Надо отметить, что весь этот AI/ML софт переживает infancy своего lifecycle. Я регулярно поглядываю на свежие версии, но вижу совершенно необъяснимые косяки и вариацию по части используемой памяти и стабильности генерации. Я думаю где-то через пару лет эта тема устаканится, чтобы это можно было назвать production grade software. Пока это сугубо для энтузиастов-исследователей.
Ну достаточно мощные сервера на эльбрусе — это на данный момент 4Э8СВ, куда до полутерабайта памяти помещается :)
А вот 16С умеет до 4 Тб на процессор (соответственно до 16 Тб на систему), но мне и на 128 Гб довелось с жабой-то потолковать; впрочем, успешно.
Насчёт оптимизации есть с кем состыковать, если кому понадобится; ну и эльбрус-вики не отменяли.
А вот 16С умеет до 4 Тб на процессор
Михаил, на официальном сайте МЦСТ (http://www.mcst.ru/elbrus-16s), для Эльбрус-16С заявлена поддержка максимум 1 Тб на процессор. Не могли бы пруфы подвести?
В той ревизии процессора, которую только отдали на производство (после чего тайваньские господа решили простить свои долги всем русским), должно было поддерживаться 4 ТБ, а вот в предыдущей ревизии - максимум 1 ТБ.
http://old.mcst.ru/files/61c195/f2dece/61d641/e4549f/sber_kommentariy_mtsst.pdf
До 16 ТБ на 4-процессорный сервер, соответственно до 4 ТБ на процессор.
Про производительность
запустите генерацию в режиме запроса без чата, ключ -p оно выведет ответ и завершит работу, показав подробную статистику по скорости, интересует два числа, токены в секунду и проходы (runs) в секунду, на i5-12600 с 6 ядрами (12 потоков) это 1сек на run (не помню точные числа), что даёт по 1-3 секунд на слово
На скорость работы влияет размер сетки, наличие/отсутствии квантизации и выбранный алгоритм (их там два) во время конвертации весов. Ещё момент, количество потоков приложения не выставляй выше количества ядер, иначе нагрузку даст а скорость не вырастает, а что произойдет с Эльбрус и подавно вопрос.
Скорость работы памяти не влияет, по крайней мере выключение профиля ddr4 3600mhz->2666mhz… Возможно при не использовании квантизации будет заметно, но с ней быстрее чем без нее.
Ещё момент, код llama.cpp активно правится и периодически вылезают деградации скорости, был тред в гите где выкладывали тесты скорости по коммитам
У меня получились такие результаты, сначала для 7B модели (commit-hash a0caa34b162449b5c13b8d604573053300ff54a1):
./main -m /srv/home/kpmy/dev/llama.cpp/models/7B/ggml-model-q4_0.bin -p "Building a website can be done in 10 simple steps:" -n 512 -s 1678486056
...
llama_print_timings: load time = 12850.61 ms
llama_print_timings: sample time = 2100.08 ms / 512 runs ( 4.10 ms per run)
llama_print_timings: prompt eval time = 55385.39 ms / 271 tokens ( 204.37 ms per token)
llama_print_timings: eval time = 1018667.75 ms / 510 runs ( 1997.39 ms per run)
llama_print_timings: total time = 1085869.75 ms
А теперь для 65B модели:
./main -m /srv/home/kpmy/dev/llama.cpp/models/65B/ggml-model-q4_0.bin -p "Building a website can be done in 10 simple steps:" -n 512 -s 1678486056
...
llama_print_timings: load time = 26450.83 ms
llama_print_timings: sample time = 2600.10 ms / 512 runs ( 5.08 ms per run)
llama_print_timings: prompt eval time = 414718.80 ms / 271 tokens ( 1530.33 ms per token)
llama_print_timings: eval time = 3368699.11 ms / 510 runs ( 6605.29 ms per run)
llama_print_timings: total time = 3797947.29 ms
В system-info видно это:
system_info: n_threads = 32 / 32 | AVX = 1 | AVX2 = 1 | AVX512 = 0 | FMA = 1 | NEON = 0 | ARM_FMA = 0 | F16C = 1 | FP16_VA = 0 | WASM_SIMD = 0 | BLAS = 0 | SSE3 = 1 | VSX = 0 |
sampling: temp = 0.800000, top_k = 40, top_p = 0.950000, repeat_last_n = 64, repeat_penalty = 1.100000
generate: n_ctx = 512, n_batch = 8, n_predict = 512, n_keep = 0
llama_print_timings: sample time = 10.58 ms / 32 runs ( 0.33 ms per run)
llama_print_timings: prompt eval time = 304.90 ms / 5 tokens ( 60.98 ms per token)
llama_print_timings: eval time = 2933.95 ms / 31 runs ( 94.64 ms per run)
64B:
llama_print_timings: sample time = 11.85 ms / 32 runs ( 0.37 ms per run)
llama_print_timings: prompt eval time = 2707.89 ms / 5 tokens ( 541.58 ms per token)
llama_print_timings: eval time = 27549.84 ms / 31 runs ( 888.70 ms per run)
Не поленитесь пожалуйста, запустите эту команду, она выдаст csv на экран с результатами по разному количеству задействованных потоков
for a in {2..32};do printf "%s;" $a;./main -t $a -m /srv/home/kpmy/dev/llama.cpp/models/7B/ggml-model-q4_0.bin -p "Random joke:" -n 32 2>&1 |grep "llama_print_timings: eval time" | cut -d "(" -f 2 | grep -o -e "[0-9\.]*" ;done
тут используется ключ -n 32, ограничивающий вывод всего 32-я токенами (для бенчмарка более чем достаточно), можно поставить 16 или меньше, результат будет немного шумным но очень быстрым.
вот какой результат получил у себя я на 6-тиядерном 12th Intel i5-12600:
по X тут количество потоков, по Y — время на run (на токены точно так же выглядит).
kpmy@mamizou:~$ lscpu
Архитектура: e2k
Порядок байт: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 1
Ядер на сокет: 8
Сокетов: 4
NUMA node(s): 4
ID прроизводителя: E8C
Семейство ЦПУ: 4
Модель: 2
Имя модели: E8C
CPU MHz: 1300
BogoMIPS: 2600.00
L1d cache: 64K
L1i cache: 128K
L2 cache: 512K
L3 cache: 16384K
NUMA node0 CPU(s): 0-7
NUMA node1 CPU(s): 8-15
NUMA node2 CPU(s): 16-23
NUMA node3 CPU(s): 24-31
Спасибо, очень странно, я ожидал что если конфигурация компьютера другая, то оптимум будет на других количествах потоков, а тут так же на половине.
последний вопрос, llama.cpp собирался на машине, запущенной в режиме эмуляции x86 машины, но сам код как минимум собирается и для эплвского процессора и для малинки, т.е. есть шанс завести это нативно и посмотреть результат? я не говорю про оптимизации, просто интересно, 10х разница в скорости все же заметная.
Собирал на этой же машине, я так понимаю, она нативная, то есть этот линукс прям под e2k.
тут так же на половине
Скорее всего потому, что Hyper-Threading есть и у Intel, и у Эльбруса.
Нет SMT у Эльбруса.
Тогда зависимость действительно не до конца понятна.
Причина в отдельной микросхеме контроллера периферийных интерфейсов КПИ-2 (южный мост), пропускной способности которой хватает для двух процессоров Эльбрус, а в случае четырёх уже становится узким местом.
Это ограничение в полной мере проявило себя на СХД, поэтому в ИНЭУМ разработали материнскую плату сразу с двумя микросхемами южного моста КПИ-2, по одной на два процессора. Например, 4Э8СВ-MSWTX на базе Эльбрус-8СВ. Это решило вопрос с пропускной способностью, который и возник в данном случае.
В случае Эльбрус-16С, "южный мост" внесён в процессор и проблем с пропускной способностью в многопроцессорных серверах уже не должно быть.
есть возможность провести подобный бенчмарк на Эльбрус-16С?
Попробуйте выше в комментариях обратиться к @shigorin Михаилу Шигорину, у него имеется рабочая станция с инженерным образцом Эльбрус-16С и достаточным объёмом оперативной памяти, работающей в 8-канальном режиме.
А вообще, для задач хранения, обработки и дообучения нейросетей, недавно были представлены ПАК "Капля" и "Капель", на базе 4-процессорного сервера с Эльбрус-8СВ (2 южных моста КПИ-2) и сопроцессорами 1879ВМ8Я от НТЦ "Модуль".
Скорость работы в один поток на e8c2, на e2c3, и на e16c практический одинаковая (с поправкой на частоту). На их 128-ми битных регистрах могут выполняться до двух, иногда до трёх AVX2 интринсиков.
А вот у e8c SIMD регистры 64-х битные, один 256 битный AVX2 интринсик разбивается на четыре отдельные операции и, в лучшем случае, занимает одну ШК, на таких машинах скорость работы будет раза в два ниже.
В этой задаче не требуется работа с диском, вся модель должна рано или поздно оказаться в памяти (или в дисковом кеше ОС), после чего как там работает КПИ уже не важно.
Ну и в межпроцессорных обменах КПИ никак не участвует, - для это используются разные линки.
Сам себя поправлю: ла, программе непосредственно работа с диском нет требуется. Но машине с 16ГБ памяти вполне можно запустить в работу 40ГБ-ную модель. Файл с моделью отобразится на виртуальную память и будет постоянный процесс считывания с диска фрагментов модели, с замедление на порядок и более....
Так что, корректно сравнивать на такой машине, где достаточно физической памяти для удержания модели в ОЗУ (и нет других задач, запущенных в ОС, также жаждущих памяти). Чтоб наверняка не вытеснялась память следует указывать опцию "— mlock".
Для запуска stable diffusion можете попробовать:
https://github.com/leejet/stable-diffusion.cpp
Она базируется на той-же библиотеке ggml, что и llama.cpp
Вообще, загляните в:
https://github.com/ggerganov/ggml
Инференс разных моделей уже поддерживается.
ЛЛаМы на Эльбрусе