Documentation
¶
Index ¶
- Constants
- type AllocationMethod
- type AllocationQuerier
- type Calculator
- type Collector
- type Config
- type CostBasis
- type Exporter
- type InferenceCost
- type InferenceCostAPIProperties
- type InferenceCostProperties
- type InferenceCostResponse
- type InferenceCostSet
- type InferenceCostSetRange
- type QueryRequest
- type QueryService
- type Runner
Constants ¶
const ( AllocationModeComputeTime = "compute_time" AllocationModeMultiplier = "multiplier" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AllocationMethod ¶
type AllocationMethod string
AllocationMethod indicates how the input/output cost split was computed.
const ( // AllocationMethodComputeTime splits costs proportionally by vLLM prefill and // decode time. inputCostPerMillionTokens uses PromptTokens as the denominator // (delivered tokens); see cacheSavingsFraction for KV cache benefit. AllocationMethodComputeTime AllocationMethod = "compute_time" // AllocationMethodPrefixCachingOff splits by input / output token time; prefix // caching is explicitly disabled on the vLLM instance. cacheSavingsFraction // will be zero by configuration, not by absence of cache hits. AllocationMethodPrefixCachingOff AllocationMethod = "prefix_caching_off" // AllocationMethodMultiplier splits using a fixed output/input cost multiplier // (vLLM timing metrics unavailable). AllocationMethodMultiplier AllocationMethod = "multiplier" )
type AllocationQuerier ¶
type AllocationQuerier interface {
// ComputeAllocation returns an AllocationSet for the given time window.
ComputeAllocation(start, end time.Time) (*opencost.AllocationSet, error)
}
AllocationQuerier is the subset of the cost model needed to fetch per-model infrastructure costs. Abstracted as an interface for testability.
type Calculator ¶
type Calculator struct {
// contains filtered or unexported fields
}
Calculator computes derived cost metrics for a slice of InferenceCost structs.
func NewCalculator ¶
func NewCalculator(config *Config) *Calculator
NewCalculator creates a Calculator with the given config.
func (*Calculator) CalculateCosts ¶
func (c *Calculator) CalculateCosts(metrics []*InferenceCost)
CalculateCosts populates derived cost fields on each InferenceCost in-place.
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector gathers per-model infrastructure costs from the OpenCost allocation layer and token/timing/cache metrics from the data source.
func NewCollector ¶
func NewCollector(config *Config, querier AllocationQuerier, metricsQuerier source.MetricsQuerier) (*Collector, error)
NewCollector creates a Collector that uses the provided MetricsQuerier for inference metrics.
func (*Collector) CollectMetrics ¶
func (c *Collector) CollectMetrics(ctx context.Context, start, end time.Time) ([]*InferenceCost, error)
CollectMetrics queries all data sources and returns one InferenceCost per model/namespace combination. start and end define the time window to query; the caller is responsible for choosing appropriate boundaries (e.g. the runner uses now-interval..now; the API uses the request window).
type Config ¶
type Config struct {
// PrometheusURL is the Prometheus server endpoint for vLLM metric queries.
PrometheusURL string
// CollectionInterval is how often metrics are collected.
// Configurable via INFERENCE_COLLECTION_INTERVAL environment variable.
// Default is 2 minutes to match the core metrics emitter query window.
CollectionInterval time.Duration
// Enabled controls whether the inference cost collector runs.
Enabled bool
// ModelLabel is the Kubernetes pod label whose value equals the vLLM
// model_name metric label. Used to aggregate allocation costs by model.
ModelLabel string
// SharedInfraLabel and SharedInfraLabelValue identify shared inference
// infrastructure pods (EPP, gateway) that lack ModelLabel.
// AllocationMode controls the input/output split method.
// "compute_time" uses vLLM timing metrics (preferred).
// "multiplier" uses a fixed ratio (fallback).
AllocationMode string
// OutputTokenCostMultiplier is the output/input cost ratio used when
// AllocationMode is "multiplier".
OutputTokenCostMultiplier float64
}
Config holds configuration for the inference cost collector.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config populated from environment variables via the env package. Callers should check Enabled before starting the collector.
type CostBasis ¶
type CostBasis string
CostBasis defines whether costs are usage-based or allocation-based.
const ( // CostBasisUsage measures actual resource consumption only. // Does not reconcile to the infrastructure bill — idle and waste are unattributed. CostBasisUsage CostBasis = "usage" // CostBasisAllocation measures max(request,usage) × runtime × price plus idle // (ShareWeighted) and shared infra (EPP, gateway). Reconciles to the bill. CostBasisAllocation CostBasis = "allocation" )
type Exporter ¶
type Exporter struct {
// contains filtered or unexported fields
}
Exporter registers and emits the llm_* Prometheus metrics.
func NewExporter ¶
func NewExporter() *Exporter
NewExporter creates an Exporter with all gauge vectors initialised.
func (*Exporter) Export ¶
func (e *Exporter) Export(metrics []*InferenceCost)
Export sets gauge values for all metrics derived from the given InferenceCost slice. Gauges are reset before each export so decommissioned models do not persist.
type InferenceCost ¶
type InferenceCost struct {
Properties InferenceCostProperties
// Window is the time range over which these costs were collected.
// Used to normalize total costs to hourly rates for Prometheus metrics.
Window struct {
Start time.Time
End time.Time
}
// Costs from OpenCost allocation layer.
// AllocationTotalCost = max(request,usage)×price + idle share + shared infra share.
AllocationTotalCost float64
// UsageTotalCost = actual_usage×price only; does not reconcile to bill.
UsageTotalCost float64
// Token counts from vLLM Prometheus metrics.
PromptTokens float64
GenerationTokens float64
TotalTokens float64
// Processing times from vLLM Prometheus metrics (seconds in collection window).
InputProcessingTime float64
OutputProcessingTime float64
// KV cache data from vLLM Prometheus metrics.
// CachedTokens is the number of prompt tokens served from the KV cache,
// sourced directly from vllm:prefix_cache_hits_total (token-level counter).
// Zero when the metric is unavailable.
CachedTokens float64
// PrefixCachingEnabled reflects the enable_prefix_caching label from
// vllm:cache_config_info. False when the metric is absent.
PrefixCachingEnabled bool
// CacheConfigKnown is true when vllm:cache_config_info was successfully
// joined for this model. When false, PrefixCachingEnabled is meaningless.
CacheConfigKnown bool
// EffectiveInputTokens is PromptTokens - CachedTokens when cache correction
// is enabled, otherwise equals PromptTokens.
EffectiveInputTokens float64
// CacheSavingsFraction is CachedTokens / PromptTokens, clamped to [0, 1].
// Represents the fraction of prompt tokens served from the KV cache. Zero
// when PromptTokens is zero or prefix caching is disabled. The raw ratio can
// exceed 1 in high-reuse workloads; see apitypes.go for the full explanation.
CacheSavingsFraction float64
// InputCost and OutputCost are the dollar amounts attributed to input and
// output processing respectively.
InputCost map[CostBasis]float64
OutputCost map[CostBasis]float64
// AllocationMethod records which input/output split path was used.
AllocationMethod AllocationMethod
// Derived cost-per-million-token metrics, keyed by CostBasis.
// Blended (input+output together), using TotalTokens as denominator.
CostPerMillionTokens map[CostBasis]float64
// Per-million input tokens, using PromptTokens as denominator.
InputCostPerMillionTokens map[CostBasis]float64
// Per-million output tokens, using GenerationTokens as denominator.
OutputCostPerMillionTokens map[CostBasis]float64
Timestamp time.Time
}
InferenceCost holds all cost data for a single model/namespace over a collection interval.
type InferenceCostAPIProperties ¶
type InferenceCostAPIProperties struct {
ModelName string `json:"modelName"`
ModelVersion string `json:"modelVersion,omitempty"`
Namespace string `json:"namespace"`
Cluster string `json:"cluster,omitempty"`
Pod string `json:"pod,omitempty"`
Controller string `json:"controller,omitempty"`
ControllerKind string `json:"controllerKind,omitempty"`
Container string `json:"container,omitempty"`
WorkloadType string `json:"workloadType"` // currently always "inference"
}
InferenceCostAPIProperties is the JSON-facing properties struct for API responses. It mirrors InferenceCostProperties but with explicit JSON tags matching the design doc field names.
type InferenceCostProperties ¶
type InferenceCostProperties struct {
ModelName string
ModelVersion string
Namespace string
Cluster string
Pod string
Controller string
ControllerKind string
Container string
WorkloadType string
}
InferenceCostProperties identifies a unique inference cost entity.
type InferenceCostResponse ¶
type InferenceCostResponse struct {
Properties InferenceCostAPIProperties `json:"properties"`
Window opencost.Window `json:"window"`
// CostBasis identifies whether these costs are usage-based or
// allocation-based. Set from the QueryRequest.
CostBasis CostBasis `json:"costBasis"`
// Total infrastructure cost for the window under the chosen cost basis.
TotalCost float64 `json:"totalCost"`
// Token counts from vLLM metrics.
PromptTokens float64 `json:"promptTokens"`
GenerationTokens float64 `json:"generationTokens"`
TotalTokens float64 `json:"totalTokens"`
// Blended cost per 1M delivered tokens (input + output together).
CostPerMillionTokens float64 `json:"costPerMillionTokens"`
// Input/output cost split. InputCost and OutputCost sum to TotalCost if the cost basis is allocation.
InputCost float64 `json:"inputCost"`
OutputCost float64 `json:"outputCost"`
// Per-million cost metrics for differentiated pricing.
// InputCostPerMillionTokens uses PromptTokens as the denominator (all delivered
// input tokens, including those served from KV cache).
InputCostPerMillionTokens float64 `json:"inputCostPerMillionTokens"`
OutputCostPerMillionTokens float64 `json:"outputCostPerMillionTokens"`
// CacheSavingsFraction is the fraction of prompt tokens served from the KV
// cache (CachedTokens / PromptTokens, clamped to [0, 1]). Zero when prefix
// caching is disabled (see allocationMethod) or when no cache hits occurred
// in the window.
//
// Note: in workloads with heavy prefix reuse (e.g. benchmarks with long
// shared system prompts), the raw ratio can exceed 1.0 because
// vllm:prefix_cache_hits_total counts tokens retrieved from cache per
// request — including prefixes established by earlier requests outside the
// current window — while vllm:prompt_tokens_total only counts new input
// tokens delivered in this window. The value is clamped to 1.0 in that case.
CacheSavingsFraction float64 `json:"cacheSavingsFraction"`
// AllocationMethod records which input/output cost-split path was used.
// Informational; omitted when empty.
AllocationMethod AllocationMethod `json:"allocationMethod,omitempty"`
// contains filtered or unexported fields
}
InferenceCostResponse is the flat, per-cost-basis API representation of inference costs for a single model/namespace in a time window. It is projected from the internal InferenceCost struct (which stores costs keyed by CostBasis) so that the JSON output matches the design doc shape exactly.
type InferenceCostSet ¶
type InferenceCostSet struct {
InferenceCosts map[string]*InferenceCostResponse `json:"inferenceCosts"`
Window opencost.Window `json:"window"`
}
InferenceCostSet holds a collection of InferenceCostResponses for a single time window, keyed by aggregation key.
type InferenceCostSetRange ¶
type InferenceCostSetRange struct {
InferenceCostSets []*InferenceCostSet `json:"inferenceCostSets"`
Window opencost.Window `json:"window"`
}
InferenceCostSetRange holds multiple InferenceCostSets covering a broader time range. Used for the /timeseries endpoint.
type QueryRequest ¶
type QueryRequest struct {
Start time.Time
End time.Time
CostBasis CostBasis
AggregateBy []string
Accumulate opencost.AccumulateOption
Filter []filterSpec
Step time.Duration
}
QueryRequest holds the parsed parameters for an inference cost query.
func ParseInferenceCostRequest ¶
func ParseInferenceCostRequest(qp mapper.PrimitiveMap) (*QueryRequest, error)
ParseInferenceCostRequest parses the common query parameters from an HTTP request into a QueryRequest. It mirrors the pattern used by customcost.ParseCustomCostTotalRequest.
Required: window (RFC3339 start,end or named range). Optional: costBasis (default: allocation), aggregate, accumulate, filter.
The step field is derived from the accumulate option.
func ParseInferenceCostTimeseriesRequest ¶
func ParseInferenceCostTimeseriesRequest(qp mapper.PrimitiveMap) (*QueryRequest, error)
ParseInferenceCostTimeseriesRequest is identical to ParseInferenceCostRequest but requires the accumulate parameter (timeseries must have a defined step).
type QueryService ¶
type QueryService struct {
// contains filtered or unexported fields
}
QueryService handles HTTP requests for the /inferenceCost endpoints. It computes inference costs on demand at request time by driving the Collector and Calculator, matching the pattern of OpenCost's /allocation and /assets APIs (no stored repository).
Note: each request issues two ComputeAllocation calls per sub-window (one with idle sharing for allocation costs, one without for usage costs). This is consistent with /allocation which also recomputes from Prometheus on every request and has no result cache.
func NewQueryService ¶
func NewQueryService(c *Collector, calc *Calculator) *QueryService
NewQueryService creates a QueryService. Both collector and calculator must be non-nil; if either is nil the handlers return 501.
func (*QueryService) GetInferenceCostTimeseriesHandler ¶
func (qs *QueryService) GetInferenceCostTimeseriesHandler() func(http.ResponseWriter, *http.Request, httprouter.Params)
GetInferenceCostTimeseriesHandler returns an httprouter-compatible handler for GET /inferenceCost/timeseries.
The 'accumulate' parameter is required for this endpoint (it defines the time-series step size). All other parameters are the same as /total.
func (*QueryService) GetInferenceCostTotalHandler ¶
func (qs *QueryService) GetInferenceCostTotalHandler() func(http.ResponseWriter, *http.Request, httprouter.Params)
GetInferenceCostTotalHandler returns an httprouter-compatible handler for GET /inferenceCost/total.
Query parameters:
- window (required): RFC3339 "start,end" or named range
- costBasis: "usage" or "allocation" (default: allocation)
- aggregate: comma-separated list of dimensions (model_name, model_version, namespace, cluster)
- accumulate: hour, day, week, month (optional; controls sub-window step for large windows)
- filter: prop:value[+prop:value] (optional; Phase-1 minimal, AND semantics)
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner periodically drives the collect → calculate → export pipeline.