Add support of presence_penalty and frequency_penalty parameter

The frequency and presence penalties help reduce the likelihood of
repetitive token sequences, allowing for more varied and contextually
appropriate outputs.

By implementing these options, we can gain finer control over the AI's
behavior, leading to improved content generation.

Reference docs:
- https://platform.openai.com/docs/api-reference/chat/create#chat-create-frequency_penalty
- https://platform.openai.com/docs/api-reference/chat/create#chat-create-presence_penalty
- https://platform.openai.com/docs/advanced-usage/frequency-and-presence-penalties
This commit is contained in:
Peter Dave Hello 2024-08-16 04:32:37 +08:00
parent 7474b2c149
commit 358263b9da
15 changed files with 59 additions and 3 deletions

View File

@ -103,14 +103,14 @@ let api: ChatGPTAPI | ChatGPTUnofficialProxyAPI
})()
async function chatReplyProcess(options: RequestOptions) {
const { message, lastContext, process, systemMessage, temperature, top_p } = options
const { message, lastContext, process, systemMessage, temperature, top_p, presence_penalty, frequency_penalty } = options
try {
let options: SendMessageOptions = { timeoutMs }
if (apiModel === 'ChatGPTAPI') {
if (isNotEmptyString(systemMessage))
options.systemMessage = systemMessage
options.completionParams = { model, temperature, top_p }
options.completionParams = { model, temperature, top_p, presence_penalty, frequency_penalty }
}
if (lastContext != null) {

View File

@ -8,6 +8,8 @@ export interface RequestOptions {
systemMessage?: string
temperature?: number
top_p?: number
presence_penalty?: number
frequency_penalty?: number
}
export interface SetProxyOptions {

View File

@ -23,7 +23,7 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
res.setHeader('Content-type', 'application/octet-stream')
try {
const { prompt, options = {}, systemMessage, temperature, top_p } = req.body as RequestProps
const { prompt, options = {}, systemMessage, temperature, top_p, presence_penalty, frequency_penalty } = req.body as RequestProps
let firstChunk = true
await chatReplyProcess({
message: prompt,
@ -35,6 +35,8 @@ router.post('/chat-process', [auth, limiter], async (req, res) => {
systemMessage,
temperature,
top_p,
presence_penalty,
frequency_penalty,
})
}
catch (error) {

View File

@ -6,6 +6,8 @@ export interface RequestProps {
systemMessage: string
temperature?: number
top_p?: number
presence_penalty?: number
frequency_penalty?: number
}
export interface ChatContext {

View File

@ -41,6 +41,8 @@ export function fetchChatAPIProcess<T = any>(
systemMessage: settingStore.systemMessage,
temperature: settingStore.temperature,
top_p: settingStore.top_p,
presence_penalty: settingStore.presence_penalty,
frequency_penalty: settingStore.frequency_penalty,
}
}

View File

@ -15,6 +15,10 @@ const temperature = ref(settingStore.temperature ?? 0.5)
const top_p = ref(settingStore.top_p ?? 1)
const presence_penalty = ref(settingStore.presence_penalty ?? 0)
const frequency_penalty = ref(settingStore.frequency_penalty ?? 0)
function updateSettings(options: Partial<SettingsState>) {
settingStore.updateSetting(options)
ms.success(t('common.success'))
@ -59,6 +63,26 @@ function handleReset() {
{{ $t('common.save') }}
</NButton>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[120px]">{{ $t('setting.presence_penalty') }} </span>
<div class="flex-1">
<NSlider v-model:value="presence_penalty" :max="2" :min="-2" :step="0.1" />
</div>
<span>{{ presence_penalty }}</span>
<NButton size="tiny" text type="primary" @click="updateSettings({ presence_penalty })">
{{ $t('common.save') }}
</NButton>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[120px]">{{ $t('setting.frequency_penalty') }} </span>
<div class="flex-1">
<NSlider v-model:value="frequency_penalty" :max="2" :min="-2" :step="0.1" />
</div>
<span>{{ frequency_penalty }}</span>
<NButton size="tiny" text type="primary" @click="updateSettings({ frequency_penalty })">
{{ $t('common.save') }}
</NButton>
</div>
<div class="flex items-center space-x-4">
<span class="flex-shrink-0 w-[120px]">&nbsp;</span>
<NButton size="small" @click="handleReset">

View File

@ -79,6 +79,8 @@ export default {
openSource: 'This project is open sourced at',
freeMIT: 'free and based on the MIT license, without any form of paid behavior!',
stars: 'If you find this project helpful, please give me a Star on GitHub or give a little sponsorship, thank you!',
presence_penalty: 'Presence Penalty',
frequency_penalty: 'Frequency Penalty',
},
store: {
siderButton: 'Prompt Store',

View File

@ -78,6 +78,8 @@ export default {
openSource: 'Este proyecto es de código abierto en',
freeMIT: 'gratis y basado en la licencia MIT, ¡sin ningún tipo de comportamiento de pago!',
stars: 'Si encuentras este proyecto útil, por favor dame una Estrella en GitHub o da un pequeño patrocinio, ¡gracias!',
presence_penalty: 'Penalización de Presencia',
frequency_penalty: 'Penalización de Frecuencia',
},
store: {
siderButton: 'Tienda rápida',

View File

@ -79,6 +79,8 @@ export default {
openSource: '이 프로젝트는 다음에서 오픈 소스로 제공됩니다:',
freeMIT: '무료이며 MIT 라이선스에 기반하며, 어떠한 형태의 유료 행동도 없습니다!',
stars: '이 프로젝트가 도움이 되었다면, GitHub에서 별을 주거나 조금의 후원을 해주시면 감사하겠습니다!',
presence_penalty: '존재 패널티',
frequency_penalty: '빈도 패널티',
},
store: {
siderButton: '프롬프트 저장소',

View File

@ -79,6 +79,8 @@ export default {
openSource: 'Этот проект опубликован в открытом доступе на',
freeMIT: 'бесплатно и основан на лицензии MIT, без каких-либо форм оплаты!',
stars: 'Если вы считаете этот проект полезным, пожалуйста, поставьте мне звезду на GitHub или сделайте небольшое пожертвование, спасибо!',
presence_penalty: 'Штраф за присутствие',
frequency_penalty: 'Штраф за частоту',
},
store: {
siderButton: 'Хранилище подсказок',

View File

@ -78,6 +78,8 @@ export default {
openSource: 'Dự án này được mở nguồn tại',
freeMIT: 'miễn phí và dựa trên giấy phép MIT, không có bất kỳ hình thức hành vi trả phí nào!',
stars: 'Nếu bạn thấy dự án này hữu ích, vui lòng cho tôi một Star trên GitHub hoặc tài trợ một chút, cảm ơn bạn!',
presence_penalty: 'Hình phạt Hiện diện',
frequency_penalty: 'Hình phạt Tần suất',
},
store: {
siderButton: 'Prompt Store',

View File

@ -79,6 +79,8 @@ export default {
openSource: '此项目开源于',
freeMIT: '免费且基于 MIT 协议,没有任何形式的付费行为',
stars: '如果你觉得此项目对你有帮助,请在 GitHub 上给我一个星星或者给予一点赞助,谢谢!',
presence_penalty: '出现惩罚',
frequency_penalty: '频率惩罚',
},
store: {
siderButton: '提示词商店',

View File

@ -79,6 +79,8 @@ export default {
openSource: '此專案在此開源:',
freeMIT: '免費且基於 MIT 授權,沒有任何形式的付費行為!',
stars: '如果你覺得此專案對你有幫助,請在 GitHub 上給我一顆星,或者贊助我,謝謝!',
presence_penalty: '出現懲罰',
frequency_penalty: '頻率懲罰',
},
store: {
siderButton: '提示詞商店',

View File

@ -6,6 +6,8 @@ export interface SettingsState {
systemMessage: string
temperature: number
top_p: number
presence_penalty: number
frequency_penalty: number
}
export function defaultSetting(): SettingsState {
@ -13,6 +15,8 @@ export function defaultSetting(): SettingsState {
systemMessage: 'You are ChatGPT, a large language model trained by OpenAI. Follow the user\'s instructions carefully. Respond using markdown.',
temperature: 0.8,
top_p: 1,
presence_penalty: 0,
frequency_penalty: 0,
}
}

View File

@ -6,6 +6,12 @@ export const useSettingStore = defineStore('setting-store', {
state: (): SettingsState => getLocalState(),
actions: {
updateSetting(settings: Partial<SettingsState>) {
if (settings.presence_penalty !== undefined && (settings.presence_penalty < -2.0 || settings.presence_penalty > 2.0))
throw new Error('presence_penalty must be between -2.0 and 2.0')
if (settings.frequency_penalty !== undefined && (settings.frequency_penalty < -2.0 || settings.frequency_penalty > 2.0))
throw new Error('frequency_penalty must be between -2.0 and 2.0')
this.$state = { ...this.$state, ...settings }
this.recordState()
},