feat: publish sanitized custom.97 source
This commit is contained in:
1022 files changed
+69903
-19207
No files matched your search
+108
-8
@@ -1,6 +1,7 @@
|
||||
package perfmetrics
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -23,6 +24,11 @@ var hotBuckets sync.Map
|
||||
// hiding fields or making response-only privacy hardening changes.
|
||||
const seriesSchema = "dbcd0a3c01b55203"
|
||||
|
||||
// MaxRecentModels bounds the historical lookups made by one summary request.
|
||||
const MaxRecentModels = 50
|
||||
const recentSuccessSampleLimit = 24
|
||||
const recentSuccessHistoryHours = 7 * 24
|
||||
|
||||
func Init() {
|
||||
go flushLoop()
|
||||
}
|
||||
@@ -67,6 +73,41 @@ func RecordRelayResult(ctx context.Context, info *relaycommon.RelayInfo, apiErr
|
||||
})
|
||||
}
|
||||
|
||||
// RecordTaskResult samples one async task exactly once, at its terminal
|
||||
// transition, after the polling status CAS is won. Latency is the end-to-end
|
||||
// task duration (second resolution, unlike the ms-resolution relay samples);
|
||||
// throughput is only present when the provider reports tokens.
|
||||
func RecordTaskResult(task *model.Task, result *relaycommon.TaskInfo) {
|
||||
if task == nil {
|
||||
return
|
||||
}
|
||||
modelName := task.Properties.OriginModelName
|
||||
if bc := task.PrivateData.BillingContext; bc != nil && bc.OriginModelName != "" {
|
||||
modelName = bc.OriginModelName
|
||||
}
|
||||
endTs := task.FinishTime
|
||||
if endTs <= 0 {
|
||||
endTs = time.Now().Unix()
|
||||
}
|
||||
sample := Sample{
|
||||
Model: modelName,
|
||||
Group: task.Group,
|
||||
Success: task.Status == model.TaskStatusSuccess,
|
||||
}
|
||||
if task.SubmitTime > 0 && endTs > task.SubmitTime {
|
||||
sample.LatencyMs = (endTs - task.SubmitTime) * 1000
|
||||
}
|
||||
if sample.Success && result != nil {
|
||||
tokens := int64(cmp.Or(result.TotalTokens, result.CompletionTokens))
|
||||
genStart := cmp.Or(task.StartTime, task.SubmitTime)
|
||||
if tokens > 0 && genStart > 0 && endTs > genStart {
|
||||
sample.OutputTokens = tokens
|
||||
sample.GenerationMs = (endTs - genStart) * 1000
|
||||
}
|
||||
}
|
||||
Record(sample)
|
||||
}
|
||||
|
||||
func Record(sample Sample) {
|
||||
setting := perf_metrics_setting.GetSetting()
|
||||
if !setting.Enabled || sample.Model == "" {
|
||||
@@ -154,16 +195,43 @@ func Query(params QueryParams) (QueryResult, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
startTs, endTs := queryWindow(time.Now(), hours)
|
||||
func QuerySummaryAll(hours int, groups []string, recentModels ...string) (SummaryAllResult, error) {
|
||||
if len(recentModels) > MaxRecentModels {
|
||||
return SummaryAllResult{}, common.NewMessage("Invalid parameters")
|
||||
}
|
||||
now := time.Now()
|
||||
startTs, endTs := queryWindow(now, hours)
|
||||
recentStartTs, _ := queryWindow(now, recentSuccessHistoryHours)
|
||||
allowedGroups := allowedGroupSet(groups)
|
||||
queryStartTs := startTs
|
||||
|
||||
rows, err := model.GetPerfMetricsSummaryBucketsAll(startTs, endTs, groups)
|
||||
recentBuckets := make(map[string]map[int64]counters, len(recentModels))
|
||||
for _, name := range recentModels {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
if _, exists := recentBuckets[name]; exists {
|
||||
continue
|
||||
}
|
||||
recentBuckets[name] = map[int64]counters{}
|
||||
buckets, err := model.GetRecentPerfMetricSuccessBuckets(name, recentStartTs, endTs, groups, recentSuccessSampleLimit)
|
||||
if err != nil {
|
||||
return SummaryAllResult{}, err
|
||||
}
|
||||
for _, bucket := range buckets {
|
||||
queryStartTs = min(queryStartTs, bucket.BucketTs)
|
||||
mergeModelBucket(recentBuckets, name, bucket.BucketTs, counters{
|
||||
requestCount: bucket.RequestCount,
|
||||
successCount: bucket.SuccessCount,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
rows, err := model.GetPerfMetricsSummaryBucketsAll(queryStartTs, endTs, groups)
|
||||
if err != nil {
|
||||
return SummaryAllResult{}, err
|
||||
}
|
||||
|
||||
totals := map[string]counters{}
|
||||
modelBuckets := map[string]map[int64]counters{}
|
||||
for _, row := range rows {
|
||||
value := counters{
|
||||
@@ -173,13 +241,12 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
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 {
|
||||
k := key.(bucketKey)
|
||||
if k.bucketTs < startTs || k.bucketTs > endTs {
|
||||
if k.bucketTs > endTs {
|
||||
return true
|
||||
}
|
||||
if allowedGroups != nil {
|
||||
@@ -191,11 +258,41 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
if snap.requestCount == 0 {
|
||||
return true
|
||||
}
|
||||
mergeModelTotals(totals, k.model, snap)
|
||||
if _, requested := recentBuckets[k.model]; requested && k.bucketTs >= recentStartTs {
|
||||
mergeModelBucket(recentBuckets, k.model, k.bucketTs, snap)
|
||||
}
|
||||
if k.bucketTs < queryStartTs {
|
||||
return true
|
||||
}
|
||||
mergeModelBucket(modelBuckets, k.model, k.bucketTs, snap)
|
||||
return true
|
||||
})
|
||||
|
||||
recentSeries := make(map[string][]SuccessRatePoint, len(recentBuckets))
|
||||
for name, buckets := range recentBuckets {
|
||||
points := recentSuccessSeries(buckets)
|
||||
if len(points) == 0 {
|
||||
continue
|
||||
}
|
||||
recentSeries[name] = points[max(0, len(points)-recentSuccessSampleLimit):]
|
||||
}
|
||||
|
||||
// Requested models are summarized over the same hours as their status samples.
|
||||
totals := map[string]counters{}
|
||||
for name, buckets := range modelBuckets {
|
||||
fromTs := startTs
|
||||
if points, ok := recentSeries[name]; ok {
|
||||
fromTs = points[0].Ts
|
||||
}
|
||||
for bucketTs, value := range buckets {
|
||||
if bucketTs < fromTs {
|
||||
delete(buckets, bucketTs)
|
||||
continue
|
||||
}
|
||||
mergeModelTotals(totals, name, value)
|
||||
}
|
||||
}
|
||||
|
||||
all := counters{}
|
||||
models := make([]ModelSummary, 0, len(totals))
|
||||
for name, total := range totals {
|
||||
@@ -226,7 +323,10 @@ func QuerySummaryAll(hours int, groups []string) (SummaryAllResult, error) {
|
||||
return models[i].RequestCount > models[j].RequestCount
|
||||
})
|
||||
|
||||
return SummaryAllResult{Summary: summarize(all), WindowStart: startTs, WindowEnd: endTs, Models: models}, nil
|
||||
return SummaryAllResult{
|
||||
Summary: summarize(all), WindowStart: startTs, WindowEnd: endTs,
|
||||
Models: models, RecentSuccessSeries: recentSeries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// QueryGroups combines raw bucket counters so busy models carry their actual weight.
|
||||
|
||||
Reference in new issue
Block a user