From 560753c61f78613ffd7bd49bf2cfc1ee4cddc621 Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Wed, 22 Nov 2023 23:02:43 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=AF=E7=94=A8?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=98=BE=E7=A4=BA=E5=B7=B2=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- model/ability.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/ability.go b/model/ability.go index 2e8766a..d115724 100644 --- a/model/ability.go +++ b/model/ability.go @@ -15,8 +15,8 @@ type Ability struct { func GetGroupModels(group string) []string { var abilities []Ability - //去重 - DB.Where("`group` = ?", group).Distinct("model").Find(&abilities) + //去重 enabled = true + DB.Where("`group` = ? and enabled = ?", group, true).Find(&abilities) models := make([]string, 0, len(abilities)) for _, ability := range abilities { models = append(models, ability.Model) From 36b0db2a3ee229e0f5bf1e6c51c41bfe826bced1 Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Wed, 22 Nov 2023 23:03:40 +0800 Subject: [PATCH 2/5] record all the consume log even if quota is 0 --- controller/relay-text.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/controller/relay-text.go b/controller/relay-text.go index a009267..921c47c 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -446,12 +446,14 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { if err != nil { common.LogError(ctx, "error update user quota cache: "+err.Error()) } - if quota != 0 { - logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) - model.RecordConsumeLog(ctx, userId, channelId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent, tokenId) - model.UpdateUserUsedQuotaAndRequestCount(userId, quota) - model.UpdateChannelUsedQuota(channelId, quota) - } + // record all the consume log even if quota is 0 + logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) + model.RecordConsumeLog(ctx, userId, channelId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent, tokenId) + model.UpdateUserUsedQuotaAndRequestCount(userId, quota) + model.UpdateChannelUsedQuota(channelId, quota) + //if quota != 0 { + // + //} } }() }(c.Request.Context()) From 53ce2437366a6000bb19262b27b41de1781014ac Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Thu, 23 Nov 2023 02:56:18 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=88=A0=E9=99=A4relay-text=E4=B8=AD?= =?UTF-8?q?=E7=9A=84consumeQuota=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/relay-openai.go | 44 +++++++++++------------ controller/relay-text.go | 71 ++++++++++++++++++-------------------- 2 files changed, 55 insertions(+), 60 deletions(-) diff --git a/controller/relay-openai.go b/controller/relay-openai.go index 9b08f85..f06d8b7 100644 --- a/controller/relay-openai.go +++ b/controller/relay-openai.go @@ -88,30 +88,28 @@ func openaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*O return nil, responseText } -func openaiHandler(c *gin.Context, resp *http.Response, consumeQuota bool, promptTokens int, model string) (*OpenAIErrorWithStatusCode, *Usage) { +func openaiHandler(c *gin.Context, resp *http.Response, promptTokens int, model string) (*OpenAIErrorWithStatusCode, *Usage) { var textResponse TextResponse - if consumeQuota { - responseBody, err := io.ReadAll(resp.Body) - if err != nil { - return errorWrapper(err, "read_response_body_failed", http.StatusInternalServerError), nil - } - err = resp.Body.Close() - if err != nil { - return errorWrapper(err, "close_response_body_failed", http.StatusInternalServerError), nil - } - err = json.Unmarshal(responseBody, &textResponse) - if err != nil { - return errorWrapper(err, "unmarshal_response_body_failed", http.StatusInternalServerError), nil - } - if textResponse.Error.Type != "" { - return &OpenAIErrorWithStatusCode{ - OpenAIError: textResponse.Error, - StatusCode: resp.StatusCode, - }, nil - } - // Reset response body - resp.Body = io.NopCloser(bytes.NewBuffer(responseBody)) + responseBody, err := io.ReadAll(resp.Body) + if err != nil { + return errorWrapper(err, "read_response_body_failed", http.StatusInternalServerError), nil } + err = resp.Body.Close() + if err != nil { + return errorWrapper(err, "close_response_body_failed", http.StatusInternalServerError), nil + } + err = json.Unmarshal(responseBody, &textResponse) + if err != nil { + return errorWrapper(err, "unmarshal_response_body_failed", http.StatusInternalServerError), nil + } + if textResponse.Error.Type != "" { + return &OpenAIErrorWithStatusCode{ + OpenAIError: textResponse.Error, + StatusCode: resp.StatusCode, + }, nil + } + // Reset response body + resp.Body = io.NopCloser(bytes.NewBuffer(responseBody)) // We shouldn't set the header before we parse the response body, because the parse part may fail. // And then we will have to send an error response, but in this case, the header has already been set. // So the httpClient will be confused by the response. @@ -120,7 +118,7 @@ func openaiHandler(c *gin.Context, resp *http.Response, consumeQuota bool, promp c.Writer.Header().Set(k, v[0]) } c.Writer.WriteHeader(resp.StatusCode) - _, err := io.Copy(c.Writer, resp.Body) + _, err = io.Copy(c.Writer, resp.Body) if err != nil { return errorWrapper(err, "copy_response_body_failed", http.StatusInternalServerError), nil } diff --git a/controller/relay-text.go b/controller/relay-text.go index 921c47c..1c44736 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -50,10 +50,9 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { channelId := c.GetInt("channel_id") tokenId := c.GetInt("token_id") userId := c.GetInt("id") - consumeQuota := c.GetBool("consume_quota") group := c.GetString("group") var textRequest GeneralOpenAIRequest - if consumeQuota || channelType == common.ChannelTypeAzure || channelType == common.ChannelTypePaLM { + if channelType == common.ChannelTypeAzure || channelType == common.ChannelTypePaLM { err := common.UnmarshalBodyReusable(c, &textRequest) if err != nil { return errorWrapper(err, "bind_request_body_failed", http.StatusBadRequest) @@ -236,7 +235,7 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { preConsumedQuota = 0 //common.LogInfo(c.Request.Context(), fmt.Sprintf("user %d has enough quota %d, trusted and no need to pre-consume", userId, userQuota)) } - if consumeQuota && preConsumedQuota > 0 { + if preConsumedQuota > 0 { userQuota, err = model.PreConsumeTokenQuota(tokenId, preConsumedQuota) if err != nil { return errorWrapper(err, "pre_consume_token_quota_failed", http.StatusForbidden) @@ -420,41 +419,39 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { defer func(ctx context.Context) { // c.Writer.Flush() go func() { - if consumeQuota { - quota := 0 - completionRatio := common.GetCompletionRatio(textRequest.Model) - promptTokens = textResponse.Usage.PromptTokens - completionTokens = textResponse.Usage.CompletionTokens + quota := 0 + completionRatio := common.GetCompletionRatio(textRequest.Model) + promptTokens = textResponse.Usage.PromptTokens + completionTokens = textResponse.Usage.CompletionTokens - quota = promptTokens + int(float64(completionTokens)*completionRatio) - quota = int(float64(quota) * ratio) - if ratio != 0 && quota <= 0 { - quota = 1 - } - totalTokens := promptTokens + completionTokens - if totalTokens == 0 { - // in this case, must be some error happened - // we cannot just return, because we may have to return the pre-consumed quota - quota = 0 - } - quotaDelta := quota - preConsumedQuota - err := model.PostConsumeTokenQuota(tokenId, userQuota, quotaDelta, preConsumedQuota, true) - if err != nil { - common.LogError(ctx, "error consuming token remain quota: "+err.Error()) - } - err = model.CacheUpdateUserQuota(userId) - if err != nil { - common.LogError(ctx, "error update user quota cache: "+err.Error()) - } - // record all the consume log even if quota is 0 - logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) - model.RecordConsumeLog(ctx, userId, channelId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent, tokenId) - model.UpdateUserUsedQuotaAndRequestCount(userId, quota) - model.UpdateChannelUsedQuota(channelId, quota) - //if quota != 0 { - // - //} + quota = promptTokens + int(float64(completionTokens)*completionRatio) + quota = int(float64(quota) * ratio) + if ratio != 0 && quota <= 0 { + quota = 1 } + totalTokens := promptTokens + completionTokens + if totalTokens == 0 { + // in this case, must be some error happened + // we cannot just return, because we may have to return the pre-consumed quota + quota = 0 + } + quotaDelta := quota - preConsumedQuota + err := model.PostConsumeTokenQuota(tokenId, userQuota, quotaDelta, preConsumedQuota, true) + if err != nil { + common.LogError(ctx, "error consuming token remain quota: "+err.Error()) + } + err = model.CacheUpdateUserQuota(userId) + if err != nil { + common.LogError(ctx, "error update user quota cache: "+err.Error()) + } + // record all the consume log even if quota is 0 + logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) + model.RecordConsumeLog(ctx, userId, channelId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent, tokenId) + model.UpdateUserUsedQuotaAndRequestCount(userId, quota) + model.UpdateChannelUsedQuota(channelId, quota) + //if quota != 0 { + // + //} }() }(c.Request.Context()) switch apiType { @@ -468,7 +465,7 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { textResponse.Usage.CompletionTokens = countTokenText(responseText, textRequest.Model) return nil } else { - err, usage := openaiHandler(c, resp, consumeQuota, promptTokens, textRequest.Model) + err, usage := openaiHandler(c, resp, promptTokens, textRequest.Model) if err != nil { return err } From 79492584b9473be85111f36d5c7d01b98245bb81 Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Thu, 23 Nov 2023 03:06:04 +0800 Subject: [PATCH 4/5] record relay time --- controller/relay-text.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/controller/relay-text.go b/controller/relay-text.go index 1c44736..9b68504 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -51,12 +51,12 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { tokenId := c.GetInt("token_id") userId := c.GetInt("id") group := c.GetString("group") + startTime := time.Now() var textRequest GeneralOpenAIRequest - if channelType == common.ChannelTypeAzure || channelType == common.ChannelTypePaLM { - err := common.UnmarshalBodyReusable(c, &textRequest) - if err != nil { - return errorWrapper(err, "bind_request_body_failed", http.StatusBadRequest) - } + + err := common.UnmarshalBodyReusable(c, &textRequest) + if err != nil { + return errorWrapper(err, "bind_request_body_failed", http.StatusBadRequest) } if relayMode == RelayModeModerations && textRequest.Model == "" { textRequest.Model = "text-moderation-latest" @@ -198,7 +198,6 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { } var promptTokens int var completionTokens int - var err error switch relayMode { case RelayModeChatCompletions: promptTokens, err = countTokenMessages(textRequest.Messages, textRequest.Model) @@ -445,7 +444,8 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { common.LogError(ctx, "error update user quota cache: "+err.Error()) } // record all the consume log even if quota is 0 - logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) + useTimeSeconds := time.Now().Unix() - startTime.Unix() + logContent := fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f,用时 %d秒", modelRatio, groupRatio, useTimeSeconds) model.RecordConsumeLog(ctx, userId, channelId, promptTokens, completionTokens, textRequest.Model, tokenName, quota, logContent, tokenId) model.UpdateUserUsedQuotaAndRequestCount(userId, quota) model.UpdateChannelUsedQuota(channelId, quota) From 3808ae8dcabaab9d019e4c6cd34e987170af7ac9 Mon Sep 17 00:00:00 2001 From: CaIon <1808837298@qq.com> Date: Thu, 23 Nov 2023 03:48:30 +0800 Subject: [PATCH 5/5] add sqlite busy_timeout=5000 --- common/database.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/database.go b/common/database.go index c7e9fd5..c8f59a8 100644 --- a/common/database.go +++ b/common/database.go @@ -3,4 +3,4 @@ package common var UsingSQLite = false var UsingPostgreSQL = false -var SQLitePath = "one-api.db" +var SQLitePath = "one-api.db?_busy_timeout=5000"