Инструмент проверки ничего не проверял: как Ollama два дня уверяла в успехе без единой проверки
Разработчик потерял два дня на отладку Ollama, которая сообщала об успешной проверке файлов, не вычисляя хеш. Корневая причина — инструмент проверял только наличие файла по пути, но не его содержимое.
Система, которая сообщает об успехе без реальной проверки, не врёт вам. Она честно отвечает на другой вопрос: «Я запустилась» — и всё.
Когда «успех» ничего не значит
Представьте: вы устанавливаете программу, видите прогресс-бар на 100%, надпись «проверка целостности» и гордое «установка завершена». Вы закрываете терминал и идёте за чаем. А программа на самом деле не установилась. Более того — она об этом знает, но решила вас не беспокоить.
Именно это произошло с разработчиком под ником Yeriahz, который запускал AI-модели локально через Ollama — популярный инструмент для работы с нейросетями на собственном компьютере без облачных API. После серии жёстких перезагрузок виртуальной машины модели перестали работать. Каждая попытка переустановки заканчивалась сообщением «verifying sha256 digest», затем «success». И каждый раз модель оставалась недоступной.
Инструмент четыре раза подряд сообщил об успешной проверке того, что проверено не было.
Как устроено хранилище Ollama — и почему проверка должна быть бесплатной
Ollama хранит файлы моделей в папке, где каждое имя файла — это SHA256-хеш его содержимого. Это называется контент-адресуемое хранилище: чтобы узнать, цел ли файл, достаточно его хеш-сумму вычислить и сравнить с именем. Никаких баз данных, манифестов или сетевых запросов. Один вызов утилиты sha256sum — и вы знаете всё.
Именно поэтому так удивительно, что Ollama этого не делает.
Разработчик проверил файл вручную: имя содержало хеш 34bb5ab0, а реальное содержимое хешировалось в d69d411b. Несовпадение налицо. Одна команда в терминале — и причина найдена. Эта команда была доступна с момента первой неудачи.
Среди тринадцати файлов в хранилище нашлось два мёртвых. Оба прошли «проверку».
Что на самом деле значит «verifying»
Когда Ollama пишет «verifying sha256 digest», она проверяет лишь одно: существует ли файл по ожидаемому пути. Если существует — считает задачу выполненной. Повторный хеш не вычисляется. Повреждённый файл, оставшийся на месте после обрыва записи, воспринимается как «уже есть такой», прогресс-бар мгновенно заполняется и выводится «success».
Разработчик воспроизвёл это намеренно: обнулил файл, сохранив его размер (именно такое состояние остаётся после прерванной записи), перезапустил Ollama и запустил установку модели заново. Лог при запуске показал, что файл подсчитан, но не удалён. Переустановка снова выдала «verifying» и «success». Файл по-прежнему хешировался в неверное значение.
Каждый слой системы сообщал, что всё в порядке. Единственное, что противоречило — имя файла. Но его никто не читал.
Проблема, которую искали не там
Отладка заняла два дня, и значительная часть времени ушла на ложный след. Ошибка проявлялась как invalid character '\x00' looking for beginning of value — в Python-стектрейсе, пять уровней вглубь HTTP-клиента фреймворка для AI-агентов. Разработчик читал логику повторных попыток, проверял формат запросов, перезапускал сервис. Всё напрасно: причина была не в сетевом слое, а в файловой системе.
Проблема усугублялась тем, что повреждение разных файлов давало разные симптомы. Если «умирал» маленький конфигурационный файл — модель просто исчезала из списка установленных. Если повреждался один из слоёв весов — модель отображалась как рабочая, но падала при загрузке с той же загадочной ошибкой. Одна причина, два совершенно разных проявления, и ни одно не указывало на повреждённый файл.
Второй урок: исправление, которое сломало всё
Оказались, зависания виртуальной машины — тоже ошибка разработчика. Он выделил восемь виртуальных ядер на машине с восемью физическими. Когда Ollama забирала все ядра, гостевое ядро Linux не могло получить процессорное время. SSH принимал пароль, но зависал: выдать shell было некому.
В логе ядра красовалось предупреждение: soft lockup - CPU#3 stuck for 371s!. Пять ядер заблокированы.
Решение казалось очевидным — ограничить квоту CPU для сервиса. Зависания прекратились мгновенно. Но генерация текста, которая раньше работала нормально, замедлилась до шести слов за двадцать пять минут.
Проблема в том, как работает ограничение квоты. Процесс получает бюджет процессорного времени, тратит его и замораживается до следующего окна. Для параллельных задач это нормально. Для последовательных — катастрофа: каждый шаг ждёт завершения предыдущего, а бюджет исчерпан.
Правильным решением было выделить меньше ядер постоянно, а не все ядра порциями. Та же цель — противоположный результат.
Получилось замкнутый круг: жёсткие перезагрузки, вызванные нехваткой CPU, обнуляли файлы моделей. Исправление, которое должно было остановить перезагрузки, сделало работу невозможной. А два дня отладки ушли на то, чтобы понять: перед нами не две проблемы, а цепочка из одной.
Принцип, который стоит запомнить
История Ollama — не про баг в конкретном инструменте. Она про распространённую ошибку в проектировании систем проверки.
Контент-адресуемое хранилище создано для того, чтобы проверка была дешёвой и локальной. Это его главная архитектурная идея. И именно в таком хранилище проверку решили не выполнять — просто поверив на слово существованию файла. Не потому что это сложно. Не потому что это дорого. А потому что никто не подумал, что файл может существовать и при этом быть сломанным.
Проверки, которые подводят таким образом, всегда прячутся за словами, звучащими как гарантия. «Верификация». «Проверка целостности». «Success». Слово создаёт ощущение контроля, но контроля нет.
Разработчик уже сталкивался с похожим: его собственный скрипт для проверки изоляции виртуальной машины выводил зелёное «OK», которое структурно не могло не вывести. Тогда он посчитал это своей невнимательностью. Теперь он нашёл то же самое в продакшн-инструменте, чей главный принцип — верификация бесплатна и локальна.
Что изменилось
Разработчик завёл issue в репозитории Ollama (номер 17520) с воспроизводимым примером, который любой может запустить за тридцать секунд. В том же трекере уже был запрос на добавление проверки целостности (issue 16801), закрытый в июне с рекомендацией перезапустить сервер — мол, при старте он сам почистит битые загрузки. Лог разработчика показывает: при старте файл был подсчитан, но не удалён.
Для пользователей Ollama вывод простой: если модель перестала работать после сбоя, не доверяйте переустановке. Проверьте хеш вручную. Один вызов sha256sum может сэкономить дни.
Для разработчиков — вывод шире: слово «verifying» в логах ничего не гарантирует, если за ним нет реального вычисления. Проверка, которая не измеряет то, что должна защищать, — не проверка.