OpenCost 1.121.0 связывает расходы Kubernetes с токенами vLLM и показывает две разные цены одного инференса: стоимость полезной работы и полную стоимость размещения модели. Для платформенной команды это способ перестать сравнивать self-hosted LLM с внешним API по неполным данным.
Этот материал — русская адаптация статьи Симы Надлер и Алекса Мейера, опубликованной CNCF 5 августа 2026 года. Контент сайтов Linux Foundation, если не указано иное, распространяется по Creative Commons Attribution 3.0; это условие закреплено в правилах Linux Foundation. Механика и ограничения дополнительно сверены 6 августа по документации и коду тега OpenCost v1.121.0.
Счёт за кластер не отвечает на вопрос о цене модели
Обычная FinOps-разбивка хорошо показывает стоимость namespace, Pod, CPU, памяти и GPU. Но для AI-платформы этого мало. Один GPU-узел может обслуживать несколько моделей, общий gateway и KV-кэш. При этом бизнес считает запросы и токены, а облако выставляет счёт за выделенную инфраструктуру.
Из-за разрыва между двумя системами измерения возникает опасная арифметика. Команда делит активное время GPU на число токенов, получает низкую цену и объявляет self-hosting выгоднее SaaS. В расчёт не попадают часы ожидания трафика, загруженные в VRAM веса, резерв мощности и общие компоненты. Модель может эффективно считать токены, но дорого стоить в режиме готовности.
OpenCost закрывает этот разрыв для развёртываний на базе vLLM, включая llm-d. Он берёт токены и временные метрики из Prometheus, соединяет их со стоимостью ресурсов из собственного allocation layer и публикует результат на языке AI-платформы: доллары в час и стоимость миллиона токенов.
Две стоимости отвечают на разные инженерные вопросы
Главное решение OpenCost — не сводить все расходы к одному числу. Каждая метрика выходит с cost_basis=usage или cost_basis=allocation.
Usage-based стоимость учитывает фактическое потребление ресурсов во время инференса. В неё не входят idle и распределённая доля общей инфраструктуры. Эта оценка отвечает на вопрос: «Сколько стоила выполненная работа?» Она подходит для сравнения моделей, квантования и аппаратных конфигураций при сопоставимой нагрузке.
Allocation-based стоимость включает max(request, usage) × price, долю простоя и общих компонентов. Она должна сходиться со счётом за инфраструктуру и отвечает на вопрос: «Сколько нам стоит держать модель доступной?» Именно её следует сравнивать с ценой внешнего API и использовать для showback или chargeback.
Предположим, активный инференс стоит 1 доллар за миллион токенов, а полная стоимость размещения — 4 доллара. Внешний API продаёт миллион токенов за 2 доллара. Сравнение только с usage даёт ложную экономию вдвое; allocation показывает, что собственное размещение пока вдвое дороже. Отношение usage к allocation — 25% — заодно показывает, сколько оплаченной мощности превращается в полезную работу.
Разница между двумя числами не всегда означает расточительство. Низкая загрузка может быть осознанной платой за latency и готовность к пику. Но теперь это явный компромисс, который можно обсуждать через SLO и бюджет, а не скрытая строка в счёте.
Как OpenCost соединяет Kubernetes и поток токенов
Функция выключена по умолчанию. После INFERENCE_COST_ENABLED=true коллектор с интервалом две минуты запрашивает allocation-данные OpenCost и метрики vLLM в том же Prometheus, который задан через PROMETHEUS_SERVER_ENDPOINT.
Для базового расчёта нужны счётчики vllm:prompt_tokens_total и vllm:generation_tokens_total. Временные метрики prefill и decode позволяют разделить стоимость входных и выходных токенов по затраченному вычислительному времени. Если их нет, калькулятор переходит на фиксированное соотношение: output принимается в 2,5 раза дороже input. Это fallback, а не измеренный профиль нагрузки, поэтому его надо видеть в label allocation_method=multiplier и не смешивать с результатами compute_time.
KV-кэш тоже не исчезает из картины. Метрика llm_cache_savings_fraction показывает долю prompt-токенов, обслуженных из кэша. Сам денежный эффект отражается через сокращение prefill-time: меньше вычислительного времени относится к input. Если счётчика cache hits нет, значение останется нулевым — это ещё не доказательство, что кэш бесполезен.
Наружу выходят три Prometheus gauge: llm_total_hourly_cost, llm_cost_per_million_tokens и llm_cache_savings_fraction. Для отчётов доступны API /inferenceCost/total и /inferenceCost/timeseries; второй требует шаг накопления — час, день, неделю или месяц. Результаты можно агрегировать по модели, версии, namespace, кластеру, Pod, controller и container.
Самое хрупкое место — не формула, а labels
Стоимость Pod и токены встречаются по имени модели и namespace. Поэтому значение Kubernetes-label, заданного через INFERENCE_MODEL_LABEL — по умолчанию llm-d.ai/model, — должно точно совпадать с model_name в метриках vLLM. Namespace тоже обязан совпасть.
Ошибка выглядит обманчиво: токены в API есть, а денежные поля равны нулю и allocationMethod пуст. Это не бесплатный инференс, а неудачный join. До подключения отчётов стоит сделать предэксплуатационную проверку: сравнить model label у Pod с model_name в Prometheus для каждого deployment и добавить алерт на нулевую стоимость при ненулевом потоке токенов.
Общие компоненты — gateway, EPP или router — надо пометить llm-d.ai/inference-shared=true либо своим эквивалентом через настройки. Тогда allocation-разбор распределит их стоимость между моделями. Без этой метки часть реального счёта останется вне модели; в usage-разбор общая инфраструктура намеренно не входит.
Как внедрить расчёт без ложной точности
Начните не с chargeback, а с двухнедельного showback. Соберите оба cost basis рядом с throughput, latency и ошибками. Для каждого числа показывайте окно расчёта, модель, namespace и allocation_method. Среднюю часовую стоимость за период считайте по истории gauge, а не умножением текущего значения на длительность отчёта.
Затем разберите четыре диагностические комбинации. Высокий allocation при низком usage указывает на простой: помогут консолидация трафика, совместное размещение или выключение редко используемой модели. Высоки оба — проверьте размер модели, железо и необходимость этого качества. Оба низки — deployment, вероятно, соответствует профилю нагрузки. Низкий allocation при высоком usage требует изучить квантование, batch и соответствие ускорителя модели.
Решение build-versus-buy принимайте только по allocation-based цене и одинаковым границам. В self-hosted расчёт должны входить общие компоненты и idle, а у SaaS — фактическая цена поставщика с учётом разных тарифов input, output и скидок. Usage оставьте инженерной метрикой оптимизации.
Ограничения версии 1.121.0
На 6 августа 2026 года код и документация тега подтверждают наличие метрик, двух API и тестов для обеих стоимостных баз. Авторы исходной статьи сообщают о proof of concept на кластере со 109 GPU и 30 моделями, но это результат команды проекта, а не независимый бенчмарк.
Функция пока относится только к inference; training и fine-tuning обозначены как возможные будущие workload types. Интеграция с UI, оценка wasted GPU capacity, улучшенное распознавание idle и расчёт потенциальной экономии ещё находятся в работе. Точность зависит от цен в OpenCost, полноты Prometheus-истории и labels. Если timing-метрик нет, разделение input/output становится модельной оценкой с коэффициентом 2,5.
OpenCost 1.121.0 не делает GPU дешевле. Он делает видимой цену готовности: отдельно показывает, сколько стоит считать токены и сколько — держать модель доступной. Для платформенной команды это разница между оптимизацией ядра инференса и решением, стоит ли вообще размещать модель у себя.