Система білінгу для AI-сервісів: точний облік токенів та GPU-годин

Система білінгу для AI-сервісів: точний облік токенів та GPU-годин Зазначимо: коли AI-платформа починає обслуговувати тисячі запитів на секунду, білінг перетворюється на вузьке місце. Токени LLM тарифікуються за моделлю input/output, GPU-час — посекундно з мінімальним порогом, API-запити — з rate

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1284
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    980
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1240
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    696
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    982

Система білінгу для AI-сервісів: точний облік токенів та GPU-годин

Зазначимо: коли AI-платформа починає обслуговувати тисячі запитів на секунду, білінг перетворюється на вузьке місце. Токени LLM тарифікуються за моделлю input/output, GPU-час — посекундно з мінімальним порогом, API-запити — з rate limiting. Помилка в конфігурації — і платформа втрачає до 10% виручки. Ми будуємо білінг-системи, які синхронізують ці різнорідні ресурси в єдину модель обліку. Наші інженери мають 5+ років досвіду в розробці білінгу для високонавантажених AI-сервісів.

Як забезпечити точний облік токенів і GPU-годин?

Основна складність — комбінування кількох одиниць тарифікації в єдину систему. LLM токени (input/output) зазвичай тарифікуються окремо, з прогресивною шкалою знижок при великих обсягах. Наприклад, тариф $5 за 1M токенів знижується до $3 при об'ємі понад 100M токенів, що дає економію до 40% для великих клієнтів. GPU-години рахуються посекундно, з мінімальним часом списання — типово 10 секунд, щоб уникнути мікротранзакцій. API-запити часто лімітуються за rate з burst-квотою. Все це потрібно об'єднати в узгоджений інвойс, зрозумілий клієнту. Для кожного ресурсу ми проектуємо окрему модель даних з підтримкою tiered-цін, кредитів та мінімальних списань. Підсумкова система підтримує PostgreSQL для OLTP-операцій та ClickHouse для аналітичних агрегацій за довільний період. Гарантуємо прозорий облік з детальною розбивкою за моделлю, ендпоінтом та часовим слотом.

from dataclasses import dataclass from enum import Enum from decimal import Decimal class BillingUnit(Enum): TOKEN = "token" # 1M токенов GPU_SECOND = "gpu_second" # GPU-время REQUEST = "request" # Запрос GB_MONTH = "gb_month" # Хранилище @dataclass class PricingRule: resource: BillingUnit unit_price: Decimal tier_breaks: list # [(volume_threshold, discounted_price)] minimum_charge: Decimal = Decimal('0') PRICING = { "llm_input_token": PricingRule( resource=BillingUnit.TOKEN, unit_price=Decimal('0.000005'), # $5 per 1M tokens tier_breaks=[ (10_000_000, Decimal('0.000004')), # >10M → $4/1M (100_000_000, Decimal('0.000003')), # >100M → $3/1M ] ), "gpu_a100_second": PricingRule( resource=BillingUnit.GPU_SECOND, unit_price=Decimal('0.00089'), # ~$3.20/hour per A100 tier_breaks=[], minimum_charge=Decimal('0.01') # Минимум 10 секунд биллинга ), } 
Ресурс Одиниця вимірювання Особливості обліку
LLM токени 1M токенів Input vs output, tiered pricing
GPU-години Секунда (мінімум 10) Округлення вгору, типи GPU
API запити Штука Rate limiting, burst
Сховище GB на місяць З урахуванням реплікації

Порівняння: real-time метринг vs batch-білінг

Замість того, щоб покладатися на щогодинний batch, real-time метринг з Redis і Kafka знижує затримки списання до 10 мс. Це в 50 разів швидше традиційних підходів, що особливо важливо при high-load, де кожен запит коштує грошей. Така архітектура дозволяє скоротити втрати виручки до 10% і підвищити точність бюджетування.

Чому real-time метринг критичний для AI-білінгу?

Без real-time метрингу клієнти можуть перевищити бюджет, а платформа — втратити гроші через затримки в списанні. Ми використовуємо Redis для швидких лічильників (актуальний баланс, rate limiting) і Kafka для аудиту. P99 затримки запису події — менше 10 мс. Сертифіковані інженери гарантують відмовостійкість системи. Реалізація метрингу включає два паралельних потоки: оперативні лічильники в Redis для миттєвого контролю лімітів і чергу подій у Kafka для подальшої агрегації. Це забезпечує баланс між швидкістю та надійністю.

class UsageMeter: def __init__(self, redis_client, kafka_producer): self.redis = redis_client self.kafka = kafka_producer async def record_llm_usage(self, customer_id: str, model_id: str, input_tokens: int, output_tokens: int, request_id: str): # 1. Real-time счётчики в Redis (для rate limiting и balance checks) pipe = self.redis.pipeline() month_key = f"usage:{customer_id}:{self.current_month()}" pipe.hincrby(month_key, f"{model_id}:input_tokens", input_tokens) pipe.hincrby(month_key, f"{model_id}:output_tokens", output_tokens) pipe.expire(month_key, 60 * 60 * 24 * 40) # 40 дней await pipe.execute() # 2. Детальные события в Kafka для аудита и биллинга await self.kafka.send("usage_events", { "event_type": "llm_inference", "customer_id": customer_id, "model_id": model_id, "request_id": request_id, "input_tokens": input_tokens, "output_tokens": output_tokens, "timestamp": datetime.utcnow().isoformat() }) async def record_gpu_job(self, customer_id: str, job_id: str, gpu_type: str, duration_seconds: float): # GPU биллинг с округлением вверх до секунды billable_seconds = max(ceil(duration_seconds), 10) # Минимум 10 сек await self.kafka.send("usage_events", { "event_type": "gpu_training", "customer_id": customer_id, "job_id": job_id, "gpu_type": gpu_type, "duration_seconds": billable_seconds, "timestamp": datetime.utcnow().isoformat() }) 

Apache Kafka використовується як надійний брокер подій, а Redis — для низьколатентних лічильників. Така зв'язка перевірена в production з навантаженням понад 10 тис. подій на секунду.

Як генерувати інвойси та контролювати бюджет?

Інвойси будуються на агрегації подій з ClickHouse. Ми підтримуємо tiered-ціни, кредити та знижки. Контроль бюджету — з алертами за порогами та автоблокуванням.

class InvoiceGenerator: async def generate_monthly_invoice(self, customer_id: str, billing_period: str) -> Invoice: # Агрегация usage событий из ClickHouse usage = await self.clickhouse.query(""" SELECT model_id, sum(input_tokens) as total_input, sum(output_tokens) as total_output, sum(gpu_seconds) as total_gpu, count() as total_requests FROM usage_events WHERE customer_id = %(customer_id)s AND toYYYYMM(timestamp) = %(period)s GROUP BY model_id """, {"customer_id": customer_id, "period": billing_period}) line_items = [] total = Decimal('0') for row in usage: input_cost = self.compute_tiered_price( row['total_input'], PRICING['llm_input_token'] ) output_cost = self.compute_tiered_price( row['total_output'], PRICING['llm_output_token'] ) line_items.append({ 'description': f"{row['model_id']} - Input tokens", 'quantity': row['total_input'], 'unit': "1M tokens", 'unit_price': float(PRICING['llm_input_token'].unit_price * 1_000_000), 'amount': float(input_cost) }) total += input_cost + output_cost # Применение кредитов и скидок credits = await self.get_customer_credits(customer_id) final_amount = max(total - credits, Decimal('0')) invoice = Invoice( customer_id=customer_id, period=billing_period, line_items=line_items, subtotal=float(total), credits_applied=float(min(credits, total)), total=float(final_amount) ) # Отправка через Stripe if final_amount > 0: await self.stripe.create_invoice(customer_id, invoice) return invoice 
async def check_budget_alerts(customer_id: str): customer = await db.get_customer(customer_id) current_spend = await usage_meter.get_current_month_spend(customer_id) thresholds = [0.5, 0.8, 0.9, 1.0] # % от месячного бюджета for threshold in thresholds: alert_amount = customer.monthly_budget * threshold if current_spend >= alert_amount: alert_key = f"budget_alert:{customer_id}:{threshold}:{current_month()}" if not await redis.exists(alert_key): await send_budget_alert(customer, threshold, current_spend) await redis.setex(alert_key, 86400 * 31, "1") 
Приклад конфігурації тарифів Тарифи задаються в YAML-файлі: ресурси, tiered-ціни, мінімальні списання. Зміна тарифів займає хвилини без передеплою.

Процес розробки білінг-системи

Етап Тривалість Результат
Аналітика тарифів і метрик 2–3 дні Модель даних і специфікація
Проектування мікросервісів 3–5 днів Архітектура на діаграмах
Реалізація метрингу та білінгу 1–3 тижні Працюючий MVP
Інтеграція з платіжним шлюзом 3–5 днів Тестові транзакції
Тестування (unit, load) 5–7 днів Звіт про покриття та P99
Деплой і документація 2–3 дні Інструкція з експлуатації

Що входить в роботу

  • Повна документація API (OpenAPI/Swagger)
  • Доступ до вихідних кодів і репозиторію
  • Навчання команди замовника (2 години онлайн)
  • Підтримка протягом місяця після релізу
  • Інтеграція з обраним платіжним шлюзом (Stripe, Chargebee, PayPal)
  • Розгортання в хмарі або on-premise

Наш досвід — понад 50 реалізованих проектів у сфері AI-білінгу. Найпоширеніша причина втрат на практиці — некоректне налаштування tiered-цін при переході між ціновими порогами: без правильного розрахунку платформа нараховує менше, ніж повинна. Ще одна часта проблема — відсутність обробки edge cases: скасовані запити після початку інференсу, перервані GPU-джоби, retry-запити після таймауту. Кожен з цих сценаріїв потребує явного рішення в білінговій логіці. Ми верифікуємо тарифну модель на синтетичних даних з граничними випадками до запуску. Отримайте консультацію: зв'яжіться з нами для попереднього аудиту. Ми оцінимо складність ваших тарифів і запропонуємо терміни.