Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
049a6def
authored
May 11, 2023
by
JustSong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: able to configure ratio for more models now (close #53)
parent
929f87d1
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
75 deletions
+96
-75
common/constants.go
+0
-5
common/model-ratio.go
+52
-0
controller/relay.go
+11
-13
model/option.go
+5
-10
web/src/components/SystemSetting.js
+17
-45
web/src/helpers/utils.js
+11
-2
No files found.
common/constants.go
View file @
049a6def
...
@@ -49,11 +49,6 @@ var TurnstileSecretKey = ""
...
@@ -49,11 +49,6 @@ var TurnstileSecretKey = ""
var
QuotaForNewUser
=
100
var
QuotaForNewUser
=
100
// https://platform.openai.com/docs/models/model-endpoint-compatibility
var
RatioGPT3dot5
float64
=
2
var
RatioGPT4
float64
=
30
var
RatioGPT4_32k
float64
=
60
const
(
const
(
RoleGuestUser
=
0
RoleGuestUser
=
0
RoleCommonUser
=
1
RoleCommonUser
=
1
...
...
common/model-ratio.go
0 → 100644
View file @
049a6def
package
common
import
"encoding/json"
// https://platform.openai.com/docs/models/model-endpoint-compatibility
// https://openai.com/pricing
// TODO: when a new api is enabled, check the pricing here
var
ModelRatio
=
map
[
string
]
float64
{
"gpt-4"
:
15
,
"gpt-4-0314"
:
15
,
"gpt-4-32k"
:
30
,
"gpt-4-32k-0314"
:
30
,
"gpt-3.5-turbo"
:
1
,
"gpt-3.5-turbo-0301"
:
1
,
"text-ada-001"
:
0.2
,
"text-babbage-001"
:
0.25
,
"text-curie-001"
:
1
,
"text-davinci-002"
:
10
,
"text-davinci-003"
:
10
,
"text-davinci-edit-001"
:
10
,
"code-davinci-edit-001"
:
10
,
"whisper-1"
:
10
,
"davinci"
:
10
,
"curie"
:
10
,
"babbage"
:
10
,
"ada"
:
10
,
"text-embedding-ada-002"
:
0.25
,
"text-search-ada-doc-001"
:
10
,
"text-moderation-stable"
:
10
,
"text-moderation-latest"
:
10
,
}
func
ModelRatio2JSONString
()
string
{
jsonBytes
,
err
:=
json
.
Marshal
(
ModelRatio
)
if
err
!=
nil
{
SysError
(
"Error marshalling model ratio: "
+
err
.
Error
())
}
return
string
(
jsonBytes
)
}
func
UpdateModelRatioByJSONString
(
jsonStr
string
)
error
{
return
json
.
Unmarshal
([]
byte
(
jsonStr
),
&
ModelRatio
)
}
func
GetModelRatio
(
name
string
)
float64
{
ratio
,
ok
:=
ModelRatio
[
name
]
if
!
ok
{
SysError
(
"Model ratio not found: "
+
name
)
return
1
}
return
ratio
}
controller/relay.go
View file @
049a6def
...
@@ -118,24 +118,22 @@ func relayHelper(c *gin.Context) error {
...
@@ -118,24 +118,22 @@ func relayHelper(c *gin.Context) error {
defer
func
()
{
defer
func
()
{
if
consumeQuota
{
if
consumeQuota
{
quota
:=
0
quota
:=
0
usingGPT4
:=
strings
.
HasPrefix
(
textRequest
.
Model
,
"gpt-4"
)
completionRatio
:=
1
if
usingGPT4
{
completionRatio
=
2
}
if
isStream
{
if
isStream
{
var
t
ext
string
var
promptT
ext
string
for
_
,
message
:=
range
textRequest
.
Messages
{
for
_
,
message
:=
range
textRequest
.
Messages
{
t
ext
+=
fmt
.
Sprintf
(
"%s: %s
\n
"
,
message
.
Role
,
message
.
Content
)
promptT
ext
+=
fmt
.
Sprintf
(
"%s: %s
\n
"
,
message
.
Role
,
message
.
Content
)
}
}
text
+=
fmt
.
Sprintf
(
"%s: %s
\n
"
,
"assistant"
,
streamResponseText
)
completionText
:=
fmt
.
Sprintf
(
"%s: %s
\n
"
,
"assistant"
,
streamResponseText
)
quota
=
countToken
(
text
)
+
3
quota
=
countToken
(
promptText
)
+
countToken
(
completionText
)
*
completionRatio
+
3
}
else
{
quota
=
textResponse
.
Usage
.
TotalTokens
}
ratio
:=
common
.
RatioGPT3dot5
if
strings
.
HasPrefix
(
textRequest
.
Model
,
"gpt-4-32k"
)
{
ratio
=
common
.
RatioGPT4_32k
}
else
if
strings
.
HasPrefix
(
textRequest
.
Model
,
"gpt-4"
)
{
ratio
=
common
.
RatioGPT4
}
else
{
}
else
{
ratio
=
common
.
RatioGPT3dot5
quota
=
textResponse
.
Usage
.
PromptTokens
+
textResponse
.
Usage
.
CompletionTokens
*
completionRatio
}
}
ratio
:=
common
.
GetModelRatio
(
textRequest
.
Model
)
quota
=
int
(
float64
(
quota
)
*
ratio
)
quota
=
int
(
float64
(
quota
)
*
ratio
)
err
:=
model
.
DecreaseTokenQuota
(
tokenId
,
quota
)
err
:=
model
.
DecreaseTokenQuota
(
tokenId
,
quota
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
model/option.go
View file @
049a6def
...
@@ -47,9 +47,7 @@ func InitOptionMap() {
...
@@ -47,9 +47,7 @@ func InitOptionMap() {
common
.
OptionMap
[
"TurnstileSiteKey"
]
=
""
common
.
OptionMap
[
"TurnstileSiteKey"
]
=
""
common
.
OptionMap
[
"TurnstileSecretKey"
]
=
""
common
.
OptionMap
[
"TurnstileSecretKey"
]
=
""
common
.
OptionMap
[
"QuotaForNewUser"
]
=
strconv
.
Itoa
(
common
.
QuotaForNewUser
)
common
.
OptionMap
[
"QuotaForNewUser"
]
=
strconv
.
Itoa
(
common
.
QuotaForNewUser
)
common
.
OptionMap
[
"RatioGPT3dot5"
]
=
strconv
.
FormatFloat
(
common
.
RatioGPT3dot5
,
'f'
,
-
1
,
64
)
common
.
OptionMap
[
"ModelRatio"
]
=
common
.
ModelRatio2JSONString
()
common
.
OptionMap
[
"RatioGPT4"
]
=
strconv
.
FormatFloat
(
common
.
RatioGPT4
,
'f'
,
-
1
,
64
)
common
.
OptionMap
[
"RatioGPT4_32k"
]
=
strconv
.
FormatFloat
(
common
.
RatioGPT4_32k
,
'f'
,
-
1
,
64
)
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMap
[
"TopUpLink"
]
=
common
.
TopUpLink
common
.
OptionMapRWMutex
.
Unlock
()
common
.
OptionMapRWMutex
.
Unlock
()
options
,
_
:=
AllOption
()
options
,
_
:=
AllOption
()
...
@@ -75,7 +73,7 @@ func UpdateOption(key string, value string) error {
...
@@ -75,7 +73,7 @@ func UpdateOption(key string, value string) error {
return
nil
return
nil
}
}
func
updateOptionMap
(
key
string
,
value
string
)
{
func
updateOptionMap
(
key
string
,
value
string
)
(
err
error
)
{
common
.
OptionMapRWMutex
.
Lock
()
common
.
OptionMapRWMutex
.
Lock
()
defer
common
.
OptionMapRWMutex
.
Unlock
()
defer
common
.
OptionMapRWMutex
.
Unlock
()
common
.
OptionMap
[
key
]
=
value
common
.
OptionMap
[
key
]
=
value
...
@@ -138,13 +136,10 @@ func updateOptionMap(key string, value string) {
...
@@ -138,13 +136,10 @@ func updateOptionMap(key string, value string) {
common
.
TurnstileSecretKey
=
value
common
.
TurnstileSecretKey
=
value
case
"QuotaForNewUser"
:
case
"QuotaForNewUser"
:
common
.
QuotaForNewUser
,
_
=
strconv
.
Atoi
(
value
)
common
.
QuotaForNewUser
,
_
=
strconv
.
Atoi
(
value
)
case
"RatioGPT3dot5"
:
case
"ModelRatio"
:
common
.
RatioGPT3dot5
,
_
=
strconv
.
ParseFloat
(
value
,
64
)
err
=
common
.
UpdateModelRatioByJSONString
(
value
)
case
"RatioGPT4"
:
common
.
RatioGPT4
,
_
=
strconv
.
ParseFloat
(
value
,
64
)
case
"RatioGPT4_32k"
:
common
.
RatioGPT4_32k
,
_
=
strconv
.
ParseFloat
(
value
,
64
)
case
"TopUpLink"
:
case
"TopUpLink"
:
common
.
TopUpLink
=
value
common
.
TopUpLink
=
value
}
}
return
err
}
}
web/src/components/SystemSetting.js
View file @
049a6def
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
Divider
,
Form
,
Grid
,
Header
,
Message
}
from
'semantic-ui-react'
;
import
{
Divider
,
Form
,
Grid
,
Header
,
Message
}
from
'semantic-ui-react'
;
import
{
API
,
removeTrailingSlash
,
showError
}
from
'../helpers'
;
import
{
API
,
removeTrailingSlash
,
showError
,
verifyJSON
}
from
'../helpers'
;
const
SystemSetting
=
()
=>
{
const
SystemSetting
=
()
=>
{
let
[
inputs
,
setInputs
]
=
useState
({
let
[
inputs
,
setInputs
]
=
useState
({
...
@@ -25,9 +25,7 @@ const SystemSetting = () => {
...
@@ -25,9 +25,7 @@ const SystemSetting = () => {
TurnstileSecretKey
:
''
,
TurnstileSecretKey
:
''
,
RegisterEnabled
:
''
,
RegisterEnabled
:
''
,
QuotaForNewUser
:
0
,
QuotaForNewUser
:
0
,
RatioGPT3dot5
:
2
,
ModelRatio
:
''
,
RatioGPT4
:
30
,
RatioGPT4_32k
:
60
,
TopUpLink
:
''
TopUpLink
:
''
});
});
let
originInputs
=
{};
let
originInputs
=
{};
...
@@ -93,7 +91,7 @@ const SystemSetting = () => {
...
@@ -93,7 +91,7 @@ const SystemSetting = () => {
name
===
'TurnstileSiteKey'
||
name
===
'TurnstileSiteKey'
||
name
===
'TurnstileSecretKey'
||
name
===
'TurnstileSecretKey'
||
name
===
'QuotaForNewUser'
||
name
===
'QuotaForNewUser'
||
name
.
startsWith
(
'Ratio'
)
||
name
===
'ModelRatio'
||
name
===
'TopUpLink'
name
===
'TopUpLink'
)
{
)
{
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
setInputs
((
inputs
)
=>
({
...
inputs
,
[
name
]:
value
}));
...
@@ -111,19 +109,17 @@ const SystemSetting = () => {
...
@@ -111,19 +109,17 @@ const SystemSetting = () => {
if
(
originInputs
[
'QuotaForNewUser'
]
!==
inputs
.
QuotaForNewUser
)
{
if
(
originInputs
[
'QuotaForNewUser'
]
!==
inputs
.
QuotaForNewUser
)
{
await
updateOption
(
'QuotaForNewUser'
,
inputs
.
QuotaForNewUser
);
await
updateOption
(
'QuotaForNewUser'
,
inputs
.
QuotaForNewUser
);
}
}
if
(
originInputs
[
'RatioGPT3dot5'
]
!==
inputs
.
RatioGPT3dot5
)
{
if
(
originInputs
[
'ModelRatio'
]
!==
inputs
.
ModelRatio
)
{
await
updateOption
(
'RatioGPT3dot5'
,
inputs
.
RatioGPT3dot5
);
if
(
!
verifyJSON
(
inputs
.
ModelRatio
))
{
}
showError
(
'模型倍率不是合法的 JSON 字符串'
);
if
(
originInputs
[
'RatioGPT4'
]
!==
inputs
.
RatioGPT4
)
{
return
;
await
updateOption
(
'RatioGPT4'
,
inputs
.
RatioGPT4
);
}
}
await
updateOption
(
'ModelRatio'
,
inputs
.
ModelRatio
);
if
(
originInputs
[
'RatioGPT4_32k'
]
!==
inputs
.
RatioGPT4_32k
)
{
await
updateOption
(
'RatioGPT4_32k'
,
inputs
.
RatioGPT4_32k
);
}
}
if
(
originInputs
[
'TopUpLink'
]
!==
inputs
.
TopUpLink
)
{
if
(
originInputs
[
'TopUpLink'
]
!==
inputs
.
TopUpLink
)
{
await
updateOption
(
'TopUpLink'
,
inputs
.
TopUpLink
);
await
updateOption
(
'TopUpLink'
,
inputs
.
TopUpLink
);
}
}
}
}
;
const
submitSMTP
=
async
()
=>
{
const
submitSMTP
=
async
()
=>
{
if
(
originInputs
[
'SMTPServer'
]
!==
inputs
.
SMTPServer
)
{
if
(
originInputs
[
'SMTPServer'
]
!==
inputs
.
SMTPServer
)
{
...
@@ -278,39 +274,15 @@ const SystemSetting = () => {
...
@@ -278,39 +274,15 @@ const SystemSetting = () => {
placeholder
=
'例如发卡网站的购买链接'
placeholder
=
'例如发卡网站的购买链接'
/>
/>
<
/Form.Group
>
<
/Form.Group
>
<
Form
.
Group
widths
=
{
3
}
>
<
Form
.
Group
widths
=
'equal'
>
<
Form
.
Input
<
Form
.
TextArea
label
=
'GPT-3.5 系列模型倍率'
label
=
'模型倍率'
name
=
'RatioGPT3dot5'
name
=
'ModelRatio'
onChange
=
{
handleInputChange
}
autoComplete
=
'off'
value
=
{
inputs
.
RatioGPT3dot5
}
type
=
'number'
step
=
'0.01'
min
=
'0'
placeholder
=
'例如:2'
/>
<
Form
.
Input
label
=
'GPT-4 系列模型倍率'
name
=
'RatioGPT4'
onChange
=
{
handleInputChange
}
autoComplete
=
'off'
value
=
{
inputs
.
RatioGPT4
}
type
=
'number'
step
=
'0.01'
min
=
'0'
placeholder
=
'例如:30'
/>
<
Form
.
Input
label
=
'GPT-4 32k 系列模型倍率'
name
=
'RatioGPT4_32k'
onChange
=
{
handleInputChange
}
onChange
=
{
handleInputChange
}
style
=
{{
minHeight
:
250
,
fontFamily
:
'JetBrains Mono, Consolas'
}}
autoComplete
=
'off'
autoComplete
=
'off'
value
=
{
inputs
.
RatioGPT4_32k
}
value
=
{
inputs
.
ModelRatio
}
type
=
'number'
placeholder
=
'为一个 JSON 文本,键为模型名称,值为倍率'
step
=
'0.01'
min
=
'0'
placeholder
=
'例如:60'
/>
/>
<
/Form.Group
>
<
/Form.Group
>
<
Form
.
Button
onClick
=
{
submitOperationConfig
}
>
保存运营设置
<
/Form.Button
>
<
Form
.
Button
onClick
=
{
submitOperationConfig
}
>
保存运营设置
<
/Form.Button
>
...
...
web/src/helpers/utils.js
View file @
049a6def
...
@@ -152,4 +152,13 @@ export function downloadTextAsFile(text, filename) {
...
@@ -152,4 +152,13 @@ export function downloadTextAsFile(text, filename) {
a
.
href
=
url
;
a
.
href
=
url
;
a
.
download
=
filename
;
a
.
download
=
filename
;
a
.
click
();
a
.
click
();
}
}
\ No newline at end of file
export
const
verifyJSON
=
(
str
)
=>
{
try
{
JSON
.
parse
(
str
);
}
catch
(
e
)
{
return
false
;
}
return
true
;
};
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment