types.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package inferencecost
  2. import "time"
  3. // CostBasis defines whether costs are usage-based or allocation-based.
  4. type CostBasis string
  5. const (
  6. // CostBasisUsage measures actual resource consumption only.
  7. // Does not reconcile to the infrastructure bill — idle and waste are unattributed.
  8. CostBasisUsage CostBasis = "usage"
  9. // CostBasisAllocation measures max(request,usage) × runtime × price plus idle
  10. // (ShareWeighted) and shared infra (EPP, gateway). Reconciles to the bill.
  11. CostBasisAllocation CostBasis = "allocation"
  12. )
  13. // AllocationMethod indicates how the input/output cost split was computed.
  14. type AllocationMethod string
  15. const (
  16. // AllocationMethodComputeTime splits costs proportionally by vLLM prefill and
  17. // decode time. inputCostPerMillionTokens uses PromptTokens as the denominator
  18. // (delivered tokens); see cacheSavingsFraction for KV cache benefit.
  19. AllocationMethodComputeTime AllocationMethod = "compute_time"
  20. // AllocationMethodPrefixCachingOff splits by input / output token time; prefix
  21. // caching is explicitly disabled on the vLLM instance. cacheSavingsFraction
  22. // will be zero by configuration, not by absence of cache hits.
  23. AllocationMethodPrefixCachingOff AllocationMethod = "prefix_caching_off"
  24. // AllocationMethodMultiplier splits using a fixed output/input cost multiplier
  25. // (vLLM timing metrics unavailable).
  26. AllocationMethodMultiplier AllocationMethod = "multiplier"
  27. )
  28. // InferenceCostProperties identifies a unique inference cost entity.
  29. type InferenceCostProperties struct {
  30. ModelName string
  31. ModelVersion string
  32. Namespace string
  33. Cluster string
  34. Pod string
  35. Controller string
  36. ControllerKind string
  37. Container string
  38. WorkloadType string
  39. }
  40. // InferenceCost holds all cost data for a single model/namespace over a
  41. // collection interval.
  42. type InferenceCost struct {
  43. Properties InferenceCostProperties
  44. // Window is the time range over which these costs were collected.
  45. // Used to normalize total costs to hourly rates for Prometheus metrics.
  46. Window struct {
  47. Start time.Time
  48. End time.Time
  49. }
  50. // Costs from OpenCost allocation layer.
  51. // AllocationTotalCost = max(request,usage)×price + idle share + shared infra share.
  52. AllocationTotalCost float64
  53. // UsageTotalCost = actual_usage×price only; does not reconcile to bill.
  54. UsageTotalCost float64
  55. // Token counts from vLLM Prometheus metrics.
  56. PromptTokens float64
  57. GenerationTokens float64
  58. TotalTokens float64
  59. // Processing times from vLLM Prometheus metrics (seconds in collection window).
  60. InputProcessingTime float64
  61. OutputProcessingTime float64
  62. // KV cache data from vLLM Prometheus metrics.
  63. // CachedTokens is the number of prompt tokens served from the KV cache,
  64. // sourced directly from vllm:prefix_cache_hits_total (token-level counter).
  65. // Zero when the metric is unavailable.
  66. CachedTokens float64
  67. // PrefixCachingEnabled reflects the enable_prefix_caching label from
  68. // vllm:cache_config_info. False when the metric is absent.
  69. PrefixCachingEnabled bool
  70. // CacheConfigKnown is true when vllm:cache_config_info was successfully
  71. // joined for this model. When false, PrefixCachingEnabled is meaningless.
  72. CacheConfigKnown bool
  73. // EffectiveInputTokens is PromptTokens - CachedTokens when cache correction
  74. // is enabled, otherwise equals PromptTokens.
  75. EffectiveInputTokens float64
  76. // CacheSavingsFraction is CachedTokens / PromptTokens, clamped to [0, 1].
  77. // Represents the fraction of prompt tokens served from the KV cache. Zero
  78. // when PromptTokens is zero or prefix caching is disabled. The raw ratio can
  79. // exceed 1 in high-reuse workloads; see apitypes.go for the full explanation.
  80. CacheSavingsFraction float64
  81. // InputCost and OutputCost are the dollar amounts attributed to input and
  82. // output processing respectively.
  83. InputCost map[CostBasis]float64
  84. OutputCost map[CostBasis]float64
  85. // AllocationMethod records which input/output split path was used.
  86. AllocationMethod AllocationMethod
  87. // Derived cost-per-million-token metrics, keyed by CostBasis.
  88. // Blended (input+output together), using TotalTokens as denominator.
  89. CostPerMillionTokens map[CostBasis]float64
  90. // Per-million input tokens, using PromptTokens as denominator.
  91. InputCostPerMillionTokens map[CostBasis]float64
  92. // Per-million output tokens, using GenerationTokens as denominator.
  93. OutputCostPerMillionTokens map[CostBasis]float64
  94. Timestamp time.Time
  95. }
  96. // Config holds configuration for the inference cost collector.
  97. type Config struct {
  98. // PrometheusURL is the Prometheus server endpoint for vLLM metric queries.
  99. PrometheusURL string
  100. // CollectionInterval is how often metrics are collected.
  101. // Configurable via INFERENCE_COLLECTION_INTERVAL environment variable.
  102. // Default is 2 minutes to match the core metrics emitter query window.
  103. CollectionInterval time.Duration
  104. // Enabled controls whether the inference cost collector runs.
  105. Enabled bool
  106. // ModelLabel is the Kubernetes pod label whose value equals the vLLM
  107. // model_name metric label. Used to aggregate allocation costs by model.
  108. ModelLabel string
  109. // SharedInfraLabel and SharedInfraLabelValue identify shared inference
  110. // infrastructure pods (EPP, gateway) that lack ModelLabel.
  111. SharedInfraLabel string
  112. SharedInfraLabelValue string
  113. // AllocationMode controls the input/output split method.
  114. // "compute_time" uses vLLM timing metrics (preferred).
  115. // "multiplier" uses a fixed ratio (fallback).
  116. AllocationMode string
  117. // OutputTokenCostMultiplier is the output/input cost ratio used when
  118. // AllocationMode is "multiplier".
  119. OutputTokenCostMultiplier float64
  120. }
  121. const (
  122. AllocationModeComputeTime = "compute_time"
  123. AllocationModeMultiplier = "multiplier"
  124. defaultOutputTokenCostMultiplier = 2.5
  125. defaultModelLabel = "llm-d.ai/model"
  126. defaultSharedInfraLabel = "llm-d.ai/inference-shared"
  127. defaultSharedInfraLabelValue = "true"
  128. )
  129. // DefaultConfig returns a Config populated from environment variables via the
  130. // env package. Callers should check Enabled before starting the collector.
  131. func DefaultConfig() *Config {
  132. return &Config{
  133. PrometheusURL: getPrometheusURL(),
  134. CollectionInterval: getCollectionInterval(),
  135. Enabled: isInferenceCostEnabled(),
  136. ModelLabel: getModelLabel(),
  137. SharedInfraLabel: getSharedInfraLabel(),
  138. SharedInfraLabelValue: getSharedInfraLabelValue(),
  139. AllocationMode: AllocationModeComputeTime,
  140. OutputTokenCostMultiplier: defaultOutputTokenCostMultiplier,
  141. }
  142. }