feat(performance): add recent success rates to model summary and enhance metrics retrieval
This commit is contained in:
+67
-14
@@ -133,20 +133,23 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
startTs := endTs - int64(hours)*3600
|
||||
allowedGroups := allowedGroupSet(groups)
|
||||
|
||||
rows, err := model.GetPerfMetricsSummaryAll(startTs, endTs, groups)
|
||||
rows, err := model.GetPerfMetricsSummaryBucketsAll(startTs, endTs, groups)
|
||||
if err != nil {
|
||||
return SummaryAllResult{}, err
|
||||
}
|
||||
|
||||
totals := map[string]counters{}
|
||||
modelBuckets := map[string]map[int64]counters{}
|
||||
for _, row := range rows {
|
||||
totals[row.ModelName] = counters{
|
||||
value := counters{
|
||||
requestCount: row.RequestCount,
|
||||
successCount: row.SuccessCount,
|
||||
totalLatencyMs: row.TotalLatencyMs,
|
||||
outputTokens: row.OutputTokens,
|
||||
generationMs: row.GenerationMs,
|
||||
}
|
||||
mergeModelTotals(totals, row.ModelName, value)
|
||||
mergeModelBucket(modelBuckets, row.ModelName, row.BucketTs, value)
|
||||
}
|
||||
|
||||
hotBuckets.Range(func(key, value any) bool {
|
||||
@@ -163,13 +166,8 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
if snap.requestCount == 0 {
|
||||
return true
|
||||
}
|
||||
cur := totals[k.model]
|
||||
cur.requestCount += snap.requestCount
|
||||
cur.successCount += snap.successCount
|
||||
cur.totalLatencyMs += snap.totalLatencyMs
|
||||
cur.outputTokens += snap.outputTokens
|
||||
cur.generationMs += snap.generationMs
|
||||
totals[k.model] = cur
|
||||
mergeModelTotals(totals, k.model, snap)
|
||||
mergeModelBucket(modelBuckets, k.model, k.bucketTs, snap)
|
||||
return true
|
||||
})
|
||||
|
||||
@@ -185,11 +183,12 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
avgTps = float64(total.outputTokens) / (float64(total.generationMs) / 1000.0)
|
||||
}
|
||||
models = append(models, ModelSummary{
|
||||
ModelName: name,
|
||||
AvgLatencyMs: avgLatency,
|
||||
SuccessRate: math.Round(successRate*100) / 100,
|
||||
AvgTps: math.Round(avgTps*100) / 100,
|
||||
RequestCount: total.requestCount,
|
||||
ModelName: name,
|
||||
AvgLatencyMs: avgLatency,
|
||||
SuccessRate: math.Round(successRate*100) / 100,
|
||||
AvgTps: math.Round(avgTps*100) / 100,
|
||||
RecentSuccessRates: recentSuccessRates(modelBuckets[name], 3),
|
||||
RequestCount: total.requestCount,
|
||||
})
|
||||
}
|
||||
sort.Slice(models, func(i, j int) bool {
|
||||
@@ -199,6 +198,60 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
return SummaryAllResult{Models: models}, nil
|
||||
}
|
||||
|
||||
func mergeModelTotals(totals map[string]counters, modelName string, value counters) {
|
||||
if value.requestCount == 0 {
|
||||
return
|
||||
}
|
||||
current := totals[modelName]
|
||||
current.requestCount += value.requestCount
|
||||
current.successCount += value.successCount
|
||||
current.totalLatencyMs += value.totalLatencyMs
|
||||
current.ttftSumMs += value.ttftSumMs
|
||||
current.ttftCount += value.ttftCount
|
||||
current.outputTokens += value.outputTokens
|
||||
current.generationMs += value.generationMs
|
||||
totals[modelName] = current
|
||||
}
|
||||
|
||||
func mergeModelBucket(modelBuckets map[string]map[int64]counters, modelName string, bucketTs int64, value counters) {
|
||||
if value.requestCount == 0 {
|
||||
return
|
||||
}
|
||||
if _, ok := modelBuckets[modelName]; !ok {
|
||||
modelBuckets[modelName] = map[int64]counters{}
|
||||
}
|
||||
current := modelBuckets[modelName][bucketTs]
|
||||
current.requestCount += value.requestCount
|
||||
current.successCount += value.successCount
|
||||
current.totalLatencyMs += value.totalLatencyMs
|
||||
current.ttftSumMs += value.ttftSumMs
|
||||
current.ttftCount += value.ttftCount
|
||||
current.outputTokens += value.outputTokens
|
||||
current.generationMs += value.generationMs
|
||||
modelBuckets[modelName][bucketTs] = current
|
||||
}
|
||||
|
||||
func recentSuccessRates(buckets map[int64]counters, limit int) []float64 {
|
||||
if len(buckets) == 0 || limit <= 0 {
|
||||
return nil
|
||||
}
|
||||
timestamps := make([]int64, 0, len(buckets))
|
||||
for ts := range buckets {
|
||||
timestamps = append(timestamps, ts)
|
||||
}
|
||||
sort.Slice(timestamps, func(i, j int) bool {
|
||||
return timestamps[i] < timestamps[j]
|
||||
})
|
||||
if len(timestamps) > limit {
|
||||
timestamps = timestamps[len(timestamps)-limit:]
|
||||
}
|
||||
rates := make([]float64, 0, len(timestamps))
|
||||
for _, ts := range timestamps {
|
||||
rates = append(rates, math.Round(successRate(buckets[ts])*100)/100)
|
||||
}
|
||||
return rates
|
||||
}
|
||||
|
||||
func allowedGroupSet(groups []string) map[string]struct{} {
|
||||
if groups == nil {
|
||||
return nil
|
||||
|
||||
@@ -48,11 +48,12 @@ type QueryResult struct {
|
||||
}
|
||||
|
||||
type ModelSummary struct {
|
||||
ModelName string `json:"model_name"`
|
||||
AvgLatencyMs int64 `json:"avg_latency_ms"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
AvgTps float64 `json:"avg_tps"`
|
||||
RequestCount int64 `json:"-"`
|
||||
ModelName string `json:"model_name"`
|
||||
AvgLatencyMs int64 `json:"avg_latency_ms"`
|
||||
SuccessRate float64 `json:"success_rate"`
|
||||
AvgTps float64 `json:"avg_tps"`
|
||||
RecentSuccessRates []float64 `json:"recent_success_rates,omitempty"`
|
||||
RequestCount int64 `json:"-"`
|
||||
}
|
||||
|
||||
type SummaryAllResult struct {
|
||||
|
||||
Reference in New Issue
Block a user