Safetensors
safetensors — безопасный формат хранения весов моделей
Safetensors — открытый формат файлов для хранения весов нейросетевых моделей. Разработан Hugging Face как безопасная альтернатива формату .ckpt (Python pickle), который мог исполнять произвольный код при загрузке. Грузится быстрее, не исполняет код, ничем не уступает по функциональности.
Коротко
Коротко. Safetensors — это безопасный формат хранения весов модели. Файл выглядит как обычный архив: заголовок-JSON и сами тензоры дальше. В отличие от старого
.ckpt, при загрузке не исполняется никакой код — модель просто читается в память. Стандарт де-факто на Hugging Face и Civitai: модели Stable Diffusion, LoRA, FLUX, Llama раздаются именно так.
Что это такое
Декабрь 2022-го. По Reddit пошла волна: «Скачал чекпоинт с Civitai, после запуска заметил странную сетевую активность». Несколько пользователей действительно получили вирус через .ckpt-файл. Причина была в архитектуре формата: .ckpt — это Python pickle, и при загрузке такого файла Python исполняет код, лежащий внутри. Если кто-то заменит в файле torch.load на свой код — он запустится у вас на машине с правами вашего пользователя.
Hugging Face разработали более узкий формат safetensors для хранения тензоров без общего механизма исполнения произвольного кода при загрузке. Он получил широкую поддержку, но конкретный проект всё равно может распространять веса в другом формате.
Файл устроен просто:
- Заголовок — JSON с описанием тензоров (имена, форма, dtype, смещение в файле).
- Тензоры — сразу после заголовка, плотно упакованные байты.
Никакого исполняемого кода. Никаких сюрпризов. Загрузчик читает заголовок, маппирует байты в память, и модель готова.
Как это работает
Загрузка .safetensors в библиотеку safetensors (Python, Rust, JS) идёт по такому пути:
- Чтение заголовка. Парсится JSON в начале файла. В нём список ключей: имя тензора → форма, тип, смещение.
- mmap. Файл маппируется в виртуальную память. Это значит, что данные не копируются — операционная система отдаёт указатели в память файла.
- Тензоры по требованию. Когда модель просит
state_dict['unet.input_blocks.0.weight']— библиотека отдаёт тензор по смещению из заголовка. Лениво, без полной загрузки в RAM.
Безопасность здесь — не криптографическая, а структурная. У формата просто нет инструкций, которые можно было бы выполнить. Это как разница между PDF и .exe: один описывает данные, другой содержит код.
Пример на практике
Дизайнер скачивает checkpoint в формате .safetensors из каталога моделей.
В ComfyUI кладёт файл в models/checkpoints/. Запускает workflow. Видит в консоли:
Loading 1 model
[mmap] safetensors header: 1 ms
[mmap] tensors mapped: 28 ms
Model loaded in 3.2 s
Холодная и повторная загрузка различаются из-за файлового кэша. Поэтому формат сравнивают на одном устройстве, одинаковом файле и нескольких повторениях.
Эквивалентный checkpoint в контейнере на основе pickle может загружаться иначе, потому что:
- pickle распаковывал бы все объекты Python в RAM целиком;
- из них собирался словарь
state_dict; - словарь копировался на GPU.
Safetensors пропускает первые два шага.
LoRA, embedding'и, controlnet-веса, файлы DreamBooth — все распространяются в .safetensors. Внутри тот же формат: заголовок-JSON + данные. Для LoRA там обычно 100–500 МБ, для embedding'а — 5–30 КБ.
С чем часто путают
- Safetensors и .ckpt —
.ckptэто Python pickle, может содержать код. Safetensors — структура без кода. По функциональности идентичны. - Safetensors и GGUF — GGUF это формат для квантизованных LLM (Llama, Mistral). Safetensors хранит модель в полной точности (FP16, BF16). GGUF — в FP4, FP6, INT8, оптимизирован под CPU-инференс.
- Safetensors и ONNX — ONNX это формат всей модели вместе с архитектурой (графом операций). Safetensors хранит только веса; архитектура задаётся отдельно в коде.
- Safetensors и Pickle — pickle это общий формат сериализации Python. Может содержать любые объекты, включая исполняемый код. Safetensors — узкоспециализирован под тензоры.
- Safetensors и сжатие — формат не сжимает данные. Файлы того же размера, что и в
.ckpt. Сжатие делается отдельно (через gzip или сразу quantization).
Частые ошибки и заблуждения
- «Safetensors сжимает модель». Нет, размер тот же. Преимущество не в размере, а в безопасности и скорости загрузки.
- «Старые .ckpt-файлы безопасны, если из проверенного источника». Условно. Но «проверенный» меняется. Гораздо проще — переходить на safetensors и не зависеть от репутации.
- «Safetensors не поддерживает все типы данных». Поддерживает FP16, BF16, FP32, INT8, UINT8. Полная палитра PyTorch. Не поддерживает только нестандартные структуры (вложенные словари, Python-объекты) — но они для весов и не нужны.
- «Конвертация .ckpt → .safetensors теряет данные». Не теряет: формат хранит ровно те же числа. Конвертация идёт в одну строку Python:
save_file(torch.load(ckpt), 'out.safetensors'). - «Загружать чужой safetensors-файл совершенно безопасно». В плане кода — да. Но веса могут давать модели «закладки»: например, скрытые триггеры в LoRA, которые активируются на специфическом промпте. Это не угроза системе, но контент-риск.
Связанные термины
- Checkpoint — файл состояния модели; формат зависит от экосистемы и способа распространения.
- GGUF — альтернативный формат для квантизованных LLM.
- ONNX — формат целой модели с архитектурой, не только весов.
- LoRA — обычно распространяется как
.safetensors. - Hugging Face — главный репозиторий моделей в этом формате.
- Quantization — отдельная техника, может применяться к safetensors-весам.
- Model Merge — результат merge сохраняется в
.safetensors.
Частые вопросы
Чем .safetensors отличается от .bin?
Расширение .bin само по себе не описывает внутренний формат. В некоторых PyTorch-проектах такой файл сериализован механизмом с возможностью исполнения кода при загрузке. Safetensors предлагает более узкий формат хранения тензоров, но происхождение файла и hash всё равно важны.
Можно ли конвертировать .ckpt в .safetensors?
Да, безопасно: convert.py из библиотеки safetensors или вкладка «Convert» в AUTOMATIC1111. Результат идентичный по весам.
Поддерживает ли safetensors метаданные?
Да. В заголовке-JSON можно хранить произвольный словарь metadata: автор LoRA, версия, триггер-слова, лицензия. Многие LoRA на Civitai используют это.
Можно ли отредактировать тензоры в safetensors напрямую? Технически да: формат документирован, и можно открыть файл, прочитать байты, изменить и записать обратно. На практике почти всегда проще загрузить модель в PyTorch, изменить и сохранить.
Что внутри LoRA-файла на .safetensors?
Десятки или сотни маленьких тензоров: lora.unet.down_blocks.0.attentions.0.processor.to_q.lora.up.weight и так далее. Плюс метаданные с триггер-словом, базовой моделью, datasetом.
Поддерживают ли safetensors все фреймворки? Да: PyTorch, TensorFlow, JAX, Flax, NumPy. Есть привязки на Python, Rust, JS, C++. В ComfyUI и AUTOMATIC1111 это стандартный формат.
Главное
Safetensors — формат хранения тензоров с небольшим заголовком и плотным блоком данных. Он не использует pickle и поэтому не несёт его способности выполнить произвольный Python-код при обычной загрузке. Memory mapping может упростить и ускорить чтение, но не гарантирует фиксированного выигрыша. Конвертацию checkpoint выполняют только из доверенной среды: исходный .ckpt всё равно придётся открыть, а отсутствующие метаданные или особые структуры могут потребовать отдельной проверки.