mirror of
https://github.com/labring/sealos.git
synced 2026-09-21 05:44:43 +08:00
feat: model cost rank and ali tts (#5428)
* feat: model cost rank api * fix: ali stt
This commit is contained in:
@@ -205,3 +205,28 @@ func GetGroupDashboardModels(c *gin.Context) {
|
||||
}
|
||||
middleware.SuccessResponse(c, newEnabledModelConfigs)
|
||||
}
|
||||
|
||||
func GetModelCostRank(c *gin.Context) {
|
||||
startTime, endTime := parseTimeRange(c)
|
||||
models, err := model.GetModelCostRank("", startTime, endTime)
|
||||
if err != nil {
|
||||
middleware.ErrorResponse(c, http.StatusOK, err.Error())
|
||||
return
|
||||
}
|
||||
middleware.SuccessResponse(c, models)
|
||||
}
|
||||
|
||||
func GetGroupModelCostRank(c *gin.Context) {
|
||||
group := c.Param("group")
|
||||
if group == "" {
|
||||
middleware.ErrorResponse(c, http.StatusOK, "group is required")
|
||||
return
|
||||
}
|
||||
startTime, endTime := parseTimeRange(c)
|
||||
models, err := model.GetModelCostRank(group, startTime, endTime)
|
||||
if err != nil {
|
||||
middleware.ErrorResponse(c, http.StatusOK, err.Error())
|
||||
return
|
||||
}
|
||||
middleware.SuccessResponse(c, models)
|
||||
}
|
||||
|
||||
@@ -81,18 +81,16 @@ func CreateLogIndexes(db *gorm.DB) error {
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat ON logs (group_id, token_name, request_at)",
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat ON logs (group_id, model, request_at)",
|
||||
// used by group used tokens
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_token ON logs (group_id, request_at, token_name)",
|
||||
// used by group used models
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_model ON logs (group_id, request_at, model)",
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_model_reqat ON logs (group_id, token_name, model, request_at)",
|
||||
|
||||
// day indexes, used by dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_truncday ON logs (group_id, request_at, timestamp_trunc_by_day)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_truncday ON logs (group_id, model, request_at, timestamp_trunc_by_day)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat_truncday ON logs (group_id, token_name, request_at, timestamp_trunc_by_day)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_token_reqat_truncday ON logs (group_id, model, token_name, request_at, timestamp_trunc_by_day)",
|
||||
// hour indexes, used by dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_trunchour ON logs (group_id, request_at, timestamp_trunc_by_hour)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_trunchour ON logs (group_id, model, request_at, timestamp_trunc_by_hour)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat_trunchour ON logs (group_id, token_name, request_at, timestamp_trunc_by_hour)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_token_reqat_trunchour ON logs (group_id, model, token_name, request_at, timestamp_trunc_by_hour)",
|
||||
@@ -100,30 +98,28 @@ func CreateLogIndexes(db *gorm.DB) error {
|
||||
} else {
|
||||
indexes = []string{
|
||||
// used by global search logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_model_reqat ON logs (model, request_at) INCLUDE (code)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_model_reqat ON logs (model, request_at) INCLUDE (code, used_amount, total_tokens)",
|
||||
// global day indexes, used by global dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_model_reqat_truncday ON logs (model, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
// global hour indexes, used by global dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_model_reqat_trunchour ON logs (model, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat ON logs (group_id, token_name, request_at) INCLUDE (code)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat ON logs (group_id, token_name, request_at) INCLUDE (code, used_amount, total_tokens)",
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat ON logs (group_id, model, request_at) INCLUDE (code)",
|
||||
// used by group used tokens
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_token ON logs (group_id, request_at, token_name)",
|
||||
// used by group used models
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_model ON logs (group_id, request_at, model)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat ON logs (group_id, token_name, request_at) INCLUDE (code, used_amount, total_tokens)",
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_model_reqat ON logs (group_id, token_name, model, request_at) INCLUDE (code)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat ON logs (group_id, model, request_at) INCLUDE (code, used_amount, total_tokens)",
|
||||
// used by search group logs
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_model_reqat ON logs (group_id, token_name, model, request_at) INCLUDE (code, used_amount, total_tokens)",
|
||||
|
||||
// day indexes, used by dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_truncday ON logs (group_id, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_truncday ON logs (group_id, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_truncday ON logs (group_id, model, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat_truncday ON logs (group_id, token_name, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_token_reqat_truncday ON logs (group_id, model, token_name, request_at, timestamp_trunc_by_day) INCLUDE (code, used_amount, total_tokens)",
|
||||
// hour indexes, used by dashboard
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_trunchour ON logs (group_id, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_reqat_trunchour ON logs (group_id, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_reqat_trunchour ON logs (group_id, model, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_token_reqat_trunchour ON logs (group_id, token_name, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
"CREATE INDEX IF NOT EXISTS idx_group_model_token_reqat_trunchour ON logs (group_id, model, token_name, request_at, timestamp_trunc_by_hour) INCLUDE (code, used_amount, total_tokens)",
|
||||
@@ -1238,3 +1234,37 @@ func GetGroupModelTPM(group string, model string) (int64, error) {
|
||||
Scan(&tpm).Error
|
||||
return tpm, err
|
||||
}
|
||||
|
||||
type ModelCostRank struct {
|
||||
Model string `json:"model"`
|
||||
UsedAmount float64 `json:"used_amount"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
|
||||
func GetModelCostRank(group string, start, end time.Time) ([]*ModelCostRank, error) {
|
||||
var ranks []*ModelCostRank
|
||||
|
||||
query := LogDB.Model(&Log{}).
|
||||
Select("model, SUM(used_amount) as used_amount, COUNT(*) as total").
|
||||
Group("model").
|
||||
Order("used_amount DESC")
|
||||
|
||||
if group != "" {
|
||||
query = query.Where("group_id = ?", group)
|
||||
}
|
||||
|
||||
if !start.IsZero() && !end.IsZero() {
|
||||
query = query.Where("request_at BETWEEN ? AND ?", start, end)
|
||||
} else if !start.IsZero() {
|
||||
query = query.Where("request_at >= ?", start)
|
||||
} else if !end.IsZero() {
|
||||
query = query.Where("request_at <= ?", end)
|
||||
}
|
||||
|
||||
err := query.Scan(&ranks).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ranks, nil
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/websocket"
|
||||
json "github.com/json-iterator/go"
|
||||
"github.com/labring/sealos/service/aiproxy/middleware"
|
||||
"github.com/labring/sealos/service/aiproxy/relay/adaptor/openai"
|
||||
"github.com/labring/sealos/service/aiproxy/relay/meta"
|
||||
relaymodel "github.com/labring/sealos/service/aiproxy/relay/model"
|
||||
@@ -46,12 +46,17 @@ type STTInput struct {
|
||||
}
|
||||
|
||||
type STTParameters struct {
|
||||
Format string `json:"format"`
|
||||
SampleRate int `json:"sample_rate"`
|
||||
Format string `json:"format,omitempty"`
|
||||
SampleRate int `json:"sample_rate,omitempty"`
|
||||
}
|
||||
|
||||
type STTOutput struct {
|
||||
Text string `json:"text"`
|
||||
STTSentence STTSentence `json:"sentence"`
|
||||
}
|
||||
|
||||
type STTSentence struct {
|
||||
Text string `json:"text"`
|
||||
EndTime *int `json:"end_time"`
|
||||
}
|
||||
|
||||
type STTUsage struct {
|
||||
@@ -83,10 +88,6 @@ func ConvertSTTRequest(meta *meta.Meta, request *http.Request) (string, http.Hea
|
||||
TaskGroup: "audio",
|
||||
Function: "recognition",
|
||||
Input: STTInput{},
|
||||
Parameters: STTParameters{
|
||||
Format: "mp3",
|
||||
SampleRate: 16000,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -128,14 +129,14 @@ func STTDoRequest(meta *meta.Meta, req *http.Request) (*http.Response, error) {
|
||||
}
|
||||
|
||||
func STTDoResponse(meta *meta.Meta, c *gin.Context, _ *http.Response) (usage *relaymodel.Usage, err *relaymodel.ErrorWithStatusCode) {
|
||||
log := middleware.GetLogger(c)
|
||||
|
||||
audioData := meta.MustGet("audio_data").([]byte)
|
||||
taskID := meta.MustGet("task_id").(string)
|
||||
|
||||
conn := meta.MustGet("ws_conn").(*websocket.Conn)
|
||||
defer conn.Close()
|
||||
|
||||
output := strings.Builder{}
|
||||
|
||||
usage = &relaymodel.Usage{}
|
||||
|
||||
for {
|
||||
@@ -178,13 +179,16 @@ func STTDoResponse(meta *meta.Meta, c *gin.Context, _ *http.Response) (usage *re
|
||||
return usage, openai.ErrorWrapperWithMessage("ali_wss_write_msg_failed", "ali_wss_write_msg_failed", http.StatusInternalServerError)
|
||||
}
|
||||
case "result-generated":
|
||||
if msg.Payload.Output.Text != "" {
|
||||
log.Info("STT result: " + msg.Payload.Output.Text)
|
||||
if msg.Payload.Output.STTSentence.Text != "" {
|
||||
output.WriteString(msg.Payload.Output.STTSentence.Text)
|
||||
}
|
||||
continue
|
||||
case "task-finished":
|
||||
usage.PromptTokens = msg.Payload.Usage.Characters
|
||||
usage.TotalTokens = msg.Payload.Usage.Characters
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"text": output.String(),
|
||||
})
|
||||
return usage, nil
|
||||
case "task-failed":
|
||||
return usage, openai.ErrorWrapperWithMessage(msg.Header.ErrorMessage, msg.Header.ErrorCode, http.StatusInternalServerError)
|
||||
|
||||
@@ -40,6 +40,12 @@ func SetAPIRouter(router *gin.Engine) {
|
||||
dashboardRoute.GET("/:group/models", controller.GetGroupDashboardModels)
|
||||
}
|
||||
|
||||
modelCostRankRoute := apiRouter.Group("/model_cost_rank")
|
||||
{
|
||||
modelCostRankRoute.GET("/", controller.GetModelCostRank)
|
||||
modelCostRankRoute.GET("/:group", controller.GetGroupModelCostRank)
|
||||
}
|
||||
|
||||
groupsRoute := apiRouter.Group("/groups")
|
||||
{
|
||||
groupsRoute.GET("/", controller.GetGroups)
|
||||
|
||||
Reference in New Issue
Block a user