Найпростіший спосіб конвертувати модель у GGUF та квантизувати її
Вітаю, мене звати Демʼєн. Сьогодні хочу обговорити перетворення моделі у формат GGUF. Воно необхідне для сумісності з багатьма inference-системами, як-от Ollama або LocalAI. Заздалегідь перепрошую за ламану мову, оскільки живу майже 10 років у Штатах.
Хоча готові GGUF-файли часто доступні на таких платформах, як Hugging Face, джерело та цілісність цих файлів можуть бути сумнівними. Вони потенційно можуть містити шкідливий код, який хоч і не завдасть безпосередньої шкоди вашому комп’ютеру, але може використати ваш графічний процесор у несанкціонованих цілях.
Треба зазначити, що початкова PyTorch-модель із сумнівних джерел теж може мати вбудований зловмисний код, і конвертація власними силами в GGUF тут вже не допоможе його прибрати. Формат файлу Safetensor саме покликаний розв’язати цю проблему.
Не використовуйте моделі в PyTorch та GGUF-форматах із невідомих джерел.
📌
Моя попередня стаття про AI та LLM: Еволюція ботів з ШІ: використовуємо можливості агентів, моделей RAG і LLM.
Quantization
Квантизація — це метод зменшення 0.123456789
в 0.1234
, після Q8_0
) у два рази гірше за попередню.
Квантизація дозволяє запускати моделі із десятками і сотнями мільярдів параметрів на менш потужному обладнанні, персональних компʼютерах і навіть на Raspberry Pi.
llama.cpp container
Якщо вам потрібен Full Precision F32, F16 або будь-який інший квантований формат, використання докер-контейнера llama.cpp
є найзручнішим на macOS/Linux/Windows.
Кроки дуже прості: створимо теку, залогінимось у HuggingFace (поставте собі цей застосунок командного рядка), завантажте усі файли із PyTorch/Safetensor-моделлю. Далі конвертуємо модель: вказуємо теку, туди ж буде збережено результат, та указуємо тип виводу конвертації, f32. Для останнього кроку встановіть docker.
mkdir -p ~/models huggingface-cli login huggingface-cli download mistralai/Mistral-7B-Instruct-v0.3 --local-dir "~/models" --include "*" #Convert to GGUF docker run --rm -v "~/models":/repo ghcr.io/ggerganov/llama.cpp:full --convert "/repo" --outtype f32 ls ~/models | grep .gguf #> ggml-model-f32.gguf #Quantize from F32.gguf to Q4_K_M.bin docker run --rm -v "~/models":/repo ghcr.io/ggerganov/llama.cpp:full --quantize "/repo/ggml-model-f32.gguf" "/repo/ggml-model-Q4_K_M.bin" "Q4_K_M" ls ~/models | grep .bin #> ggml-model-Q4_K_M.bin
На виході ви отримали ggml-model-f32.gguf
файл. Це все!
Ollama App
Як варіант, використовуйте ollama --quantize
. Підтримуються GGUF моделі у F16
F32
чи Safetensors форматі:
#GGUF to q6_K echo "FROM hf.co/bartowski/Llama-3.2-3B-Instruct-GGUF:F16" > ~/models/modelfile ollama create hf.co/bartowski/Llama-3.2-1B-Instruct-GGUF:q6_K —quantize q6_K —file ~/models/modelfile ollama list #Safetensors model=sentence-transformers-testing/stsb-bert-tiny-safetensors modelname=hf.co/${model} modeldir=${PWD}/${model} mkdir -p "${modeldir}" && huggingface-cli download "${model}" --local-dir "${modeldir}" --include "*" echo "FROM ${modeldir}" > "${modeldir}/modelfile" ollama create $modelname -f ${modeldir}/modelfile ollama list | grep $modelname
Для ollama/llama.cpp
F16 вважається Full Precession, для комп’ютерів споживчого класу.
Brew та macOS
На macOS ви можете використовувати brew
, щоб встановити llama.cpp, хоча він іноді може бути ненадійним через залежності.
brew install llama.cpp ls /opt/homebrew/bin | grep llama mkdir -p ~/models huggingface-cli login huggingface-cli download "mistralai/Mistral-7B-Instruct-v0.3" --local-dir "~/models" --include "*"#Convert to GGUF llama-gguf "mistralai/Mistral-7B-Instruct-v0.3" --outtype f32#Quantize GGUF llama-quantize "mistralai/Mistral-7B-Instruct-v0.3/ggml-model-f32.gguf" "mistralai/Mistral-7B-Instruct-v0.3/Q4_K_M.bin" "Q4_K_M"
Найважчий спосіб
Це найскладніший спосіб зробити збірку з коду. Хоча часто складний через різноманітні залежності та налаштування, які вам доведеться вручну підлаштовувати під ваше середовище, ОС, обладнання графічного процесора тощо:
git clone https://github.com/ggerganov/llama.cpp cd llama.cpp make
Залежності
- Docker або Docker Desktop.
- Встановлення та вхід:
huggingface-cli login
. - На картці моделі HugginFace може вимагати прийняття умов використання.
Available options
Тлумачення назв моделей: Що означає Q#_K_M
у квантованих моделях?
У контексті llama.cpp
, Q4_K_M позначає певний тип методу квантування. Правила позначення такі:
- Q означає квантування;
- 4 вказує на кількість бітів, що використовуються у процесі квантування. Чим менше число, тим гірша якість. 32 найкраща якість;
- K вказує на використання кластеризації за методом k-середніх при квантуванні;
- M позначає розмір моделі після квантування. (S = мала, M = середня, L = велика). L більше займатиме простору, але матиме меншу втрату якості моделі;
- I = Importance Matrix (imatrix).
Що таке матриця важливості (Importance Matrix)?
Матриця важливості (imatrix) призначає оцінку важливості кожній вазі або активації в нейронній мережі. Ця оцінка важливості зазвичай розраховується на основі чутливості виходу моделі до змін у цій конкретній вазі або активації.
Матриця важливості дозволяє здійснювати цілеспрямоване квантування, коли найбільш важливі компоненти зберігаються з більшою точністю, тоді як менш важливі квантуються для економії пам’яті та обчислювальних ресурсів.
Такий цільовий підхід особливо важливий при квантуванні з дуже низькою точністю (наприклад,
Приклад: IQ3_M це квантизація 3 біт, з використанням imatrix середньої величини.
Imatrix дозволяє зменшити розмір моделі мінімізуючи втрату якості що більш важливо у випадку найбільшої компресії. Lllama.cpp підтримує imatrix для Q1, Q2, Q3 та Q4 компресії. Ollama/quantize на разі не підтримує imatrix.
llama.cpp
usage: ./llama-quantize [--help] [--allow-requantize] [--leave-output-tensor] [--pure] [--imatrix] [--include-weights] [--exclude-weights] [--output-tensor-type] [--token-embedding-type] [--override-kv] model-f32.gguf [model-quant.gguf] type [nthreads] --allow-requantize: Allows requantizing tensors that have already been quantized. Warning: This can severely reduce quality compared to quantizing from 16bit or 32bit --leave-output-tensor: Will leave output.weight un(re)quantized. Increases model size but may also increase quality, especially when requantizing --pure: Disable k-quant mixtures and quantize all tensors to the same type --imatrix file_name: use data in file_name as importance matrix for quant optimizations --include-weights tensor_name: use importance matrix for this/these tensor(s) --exclude-weights tensor_name: use importance matrix for this/these tensor(s) --output-tensor-type ggml_type: use this ggml_type for the output.weight tensor --token-embedding-type ggml_type: use this ggml_type for the token embeddings tensor --keep-split: will generate quatized model in the same shards as input --override-kv KEY=TYPE:VALUE Advanced option to override model metadata by key in the quantized model. May be specified multiple times. Note: --include-weights and --exclude-weights cannot be used together Allowed quantization types: 2 or Q4_0 : 3.56G, +0.2166 ppl @ LLaMA-v1-7B 3 or Q4_1 : 3.90G, +0.1585 ppl @ LLaMA-v1-7B 8 or Q5_0 : 4.33G, +0.0683 ppl @ LLaMA-v1-7B 9 or Q5_1 : 4.70G, +0.0349 ppl @ LLaMA-v1-7B 19 or IQ2_XXS : 2.06 bpw quantization 20 or IQ2_XS : 2.31 bpw quantization 28 or IQ2_S : 2.5 bpw quantization 29 or IQ2_M : 2.7 bpw quantization 24 or IQ1_S : 1.56 bpw quantization 31 or IQ1_M : 1.75 bpw quantization 10 or Q2_K : 2.63G, +0.6717 ppl @ LLaMA-v1-7B 21 or Q2_K_S : 2.16G, +9.0634 ppl @ LLaMA-v1-7B 23 or IQ3_XXS : 3.06 bpw quantization 26 or IQ3_S : 3.44 bpw quantization 27 or IQ3_M : 3.66 bpw quantization mix 12 or Q3_K : alias for Q3_K_M 22 or IQ3_XS : 3.3 bpw quantization 11 or Q3_K_S : 2.75G, +0.5551 ppl @ LLaMA-v1-7B 12 or Q3_K_M : 3.07G, +0.2496 ppl @ LLaMA-v1-7B 13 or Q3_K_L : 3.35G, +0.1764 ppl @ LLaMA-v1-7B 25 or IQ4_NL : 4.50 bpw non-linear quantization 30 or IQ4_XS : 4.25 bpw non-linear quantization 15 or Q4_K : alias for Q4_K_M 14 or Q4_K_S : 3.59G, +0.0992 ppl @ LLaMA-v1-7B 15 or Q4_K_M : 3.80G, +0.0532 ppl @ LLaMA-v1-7B 17 or Q5_K : alias for Q5_K_M 16 or Q5_K_S : 4.33G, +0.0400 ppl @ LLaMA-v1-7B 17 or Q5_K_M : 4.45G, +0.0122 ppl @ LLaMA-v1-7B 18 or Q6_K : 5.15G, +0.0008 ppl @ LLaMA-v1-7B 7 or Q8_0 : 6.70G, +0.0004 ppl @ LLaMA-v1-7B 1 or F16 : 14.00G, -0.0020 ppl @ Mistral-7B 32 or BF16 : 14.00G, -0.0050 ppl @ Mistral-7B 0 or F32 : 26.00G @ 7B COPY : only copy tensors, no quantizing
Ollama
ollama create mynewmodelname:q6_K —quantize q6_K —file modelfile Supported Quantizations q4_0 q4_1 q5_0 q5_1 q8_0 K-means Quantizations q3_K_S q3_K_M q3_K_L q4_K_S q4_K_M q5_K_S q5_K_M q6_K
Hugging Face GGUF Quants Q2-Q8
huggingface.co/...ces/ggml-org/gguf-my-repo
BitNet b1.58
Цікавий момент як різні сили і думки формують архітектуру сучасних LLM знаходячи баланс між декількома силами та ідеями та як швидко усе змінюється в ШІ галузі. С початку ми прийшли до ідеї чим більше тим краще: більше даних, більше параметрів більше модель. Потім ми зрозуміли що моделі виросли до якихось мега-монстрозних розмірів і вирішили їх зменшити методом квантизації. І дійшовши до крайності стиснення якості у 1 біт, ми раптом зрозуміли що можна із самого початку робити моделі не із плаваючою точкою а BitNet b1.58
. Також виявляється, що
Приклад: 1bitLLM/bitnet_b1_58-3B
Висновки
Найпростіший спосіб конвертувати PyTorch та Safetensor у GGUF та квантизувати — це використати офіційний docker-контейнер. Не використовуйте PyTorch-моделі із неперевірених джерел, вони можуть їсти ваші ресурси для виконання чужих зловмисних завдань. Квантизація дозволяє запускати великі моделі на персональних компʼютерах.
Слідуючи крокам в статті ви можете стиснути великі моделі до розміру що дозволить запускати їх на персональних компʼютерах. Для найбільшої якості моделі необхідно підібрати параметри квантизації для максимального збереження якості. Доступні варіанти квантизації дозволяють знайти баланс між якістю моделі і стисненням її розміру.
В недалекому майбутньому навчені нові b1.58 моделі займатимуть набагато менше простору у памʼяті та процесорних ресурсів що має дати значний поштовх у розвитку ШІ, так як ми зможемо або ж отримати ту саму якість використовуючи менше ресурсів компʼютера або навпаки використовувати усе ті самі ресурси на повну як і попередні моделі, але ці моделі будуть мати більше вбудованих знань і як результат будуть потенційно значно якісніші.
Підтримка
Якщо вам сподобалася ця стаття і ви хочете підтримати мене:
- Натисніть «Подобається 👍» та додайте «До обраного ⭐️» мою статтю; це допоможе мені. Також слідкуйте за мною на DOU щоб отримувати останні статті.
- Дайте відгук у коментарях нижче, навіть якщо це просте «дякую» — це допоможе мені розуміти, що моя робота була не марною. Якщо є помилки, скажіть де, а найголовніше як виправити, не претендую на роль всезнайки.
- Шукаю ентузіастів та однодумців, що знаються на Python і хотіли б втілити описані ідеї в моїх статтях у життя, і, можливо, навіть зробити сумісний проєкт: Напишіть мені в LinkedIn. На разі працю над PoC, який використовує описані принципи у моїх статтях. Буду радий поділитись своїми напрацюваннями і знаннями.
- Я готую статтю яка по великому рахунку використовує NLP для побудувати графу знань із вільного тексту, який зберігається у БД для того щоб потім бути використаним в Agentic RAG чатботі. Чи було би вам цікаво стати соовтором? Треба вичитати перевірити, виправити де не правильно, може оновити якщо щось застаріло чи додати нове. Це буде продовженням до цієї та попередньої статті. Прошу написати мені персональне повідомлення LinkedIn / Discord якщо ви хочете по співпрацювати на цю тему.
17 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів