| @@ -320,6 +320,10 @@ | ||
| 320 | 320 | "type": "novel_preset" |
| 321 | 321 | }, |
| 322 | 322 | { |
| 323 | + "filename": "presets/novel/Universal-Erato.json", | |
| 324 | + "type": "novel_preset" | |
| 325 | + }, | |
| 326 | + { | |
| 323 | 327 | "filename": "presets/textgen/Asterism.json", |
| 324 | 328 | "type": "textgen_preset" |
| 325 | 329 | }, |
| @@ -0,0 +1,29 @@ | ||
| 1 | +{ | |
| 2 | + "temperature": 1.25, | |
| 3 | + "repetition_penalty": 1.00, | |
| 4 | + "repetition_penalty_range": 0, | |
| 5 | + "repetition_penalty_slope": 0, | |
| 6 | + "repetition_penalty_frequency": 0, | |
| 7 | + "repetition_penalty_presence": 0, | |
| 8 | + "tail_free_sampling": 1, | |
| 9 | + "top_k": 0, | |
| 10 | + "top_p": 1, | |
| 11 | + "top_a": 0, | |
| 12 | + "typical_p": 1, | |
| 13 | + "min_p": 0.1, | |
| 14 | + "math1_temp": 1, | |
| 15 | + "math1_quad": 0, | |
| 16 | + "math1_quad_entropy_scale": 0, | |
| 17 | + "min_length": 1, | |
| 18 | + "prefix": "vanilla", | |
| 19 | + "cfg_uc": "", | |
| 20 | + "banned_tokens": "", | |
| 21 | + "order": [ | |
| 22 | + 0, | |
| 23 | + 10 | |
| 24 | + ], | |
| 25 | + "phrase_rep_pen": "off", | |
| 26 | + "cfg_scale": 1, | |
| 27 | + "mirostat_lr": 0, | |
| 28 | + "mirostat_tau": 0 | |
| 29 | +} | |
| @@ -2100,6 +2100,7 @@ | ||
| 2100 | 2100 | <select id="model_novel_select"> |
| 2101 | 2101 | <option value="clio-v1">Clio</option> |
| 2102 | 2102 | <option value="kayra-v1">Kayra</option> |
| 2103 | + <option value="llama-3-erato-v1">Erato</option> | |
| 2103 | 2104 | </select> |
| 2104 | 2105 | <div class="flex-container"> |
| 2105 | 2106 | <div id="api_button_novel" class="api_button menu_button menu_button_icon" type="submit" data-i18n="Connect">Connect</div> |
| @@ -4860,6 +4860,13 @@ export function getMaxContextSize(overrideResponseLength = null) { | ||
| 4860 | 4860 | console.log(`NovelAI subscription limit reached. Max context size is now ${this_max_context}`); |
| 4861 | 4861 | } |
| 4862 | 4862 | } |
| 4863 | + if (nai_settings.model_novel.includes('erato')) { | |
| 4864 | + // subscriber limits coming soon | |
| 4865 | + this_max_context = Math.min(max_context, 8192); | |
| 4866 | + | |
| 4867 | + // Added special tokens and whatnot | |
| 4868 | + this_max_context -= 1; | |
| 4869 | + } | |
| 4863 | 4870 | |
| 4864 | 4871 | this_max_context = this_max_context - (overrideResponseLength || amount_gen); |
| 4865 | 4872 | } |
| @@ -24,6 +24,7 @@ const maximum_output_length = 150; | ||
| 24 | 24 | const default_presets = { |
| 25 | 25 | 'clio-v1': 'Talker-Chat-Clio', |
| 26 | 26 | 'kayra-v1': 'Carefree-Kayra', |
| 27 | + 'llama-3-erato-v1': 'Universal-Erato', | |
| 27 | 28 | }; |
| 28 | 29 | |
| 29 | 30 | export const nai_settings = { |
| @@ -495,7 +496,14 @@ export function getNovelGenerationData(finalPrompt, settings, maxLength, isImper | ||
| 495 | 496 | console.log(finalPrompt); |
| 496 | 497 | } |
| 497 | 498 | |
| 498 | 499 | const adjustedMaxLengthisKayra = nai_settings.model_novel.includes('kayra') ? getKayraMaxResponseTokens() : maximum_output_length; |
| 500 | + const isErato = nai_settings.model_novel.includes('erato'); | |
| 501 | + | |
| 502 | + if (isErato) { | |
| 503 | + finalPrompt = '<|startoftext|>' + finalPrompt; | |
| 504 | + } | |
| 505 | + | |
| 506 | + const adjustedMaxLength = (isKayra || isErato) ? getKayraMaxResponseTokens() : maximum_output_length; | |
| 499 | 507 | |
| 500 | 508 | return { |
| 501 | 509 | 'input': finalPrompt, |
| @@ -540,7 +548,8 @@ function selectPrefix(selected_prefix, finalPrompt) { | ||
| 540 | 548 | let useInstruct = false; |
| 541 | 549 | const clio = nai_settings.model_novel.includes('clio'); |
| 542 | 550 | const kayra = nai_settings.model_novel.includes('kayra'); |
| 543 | - const isNewModel = clio || kayra; | |
| 551 | + const erato = nai_settings.model_novel.includes('erato'); | |
| 552 | + const isNewModel = clio || kayra || erato; | |
| 544 | 553 | |
| 545 | 554 | if (isNewModel) { |
| 546 | 555 | // NovelAI claims they scan backwards 1000 characters (not tokens!) to look for instruct brackets. That's really short. |
| @@ -559,6 +568,9 @@ function getTokenizerTypeForModel(model) { | ||
| 559 | 568 | if (model.includes('kayra')) { |
| 560 | 569 | return tokenizers.NERD2; |
| 561 | 570 | } |
| 571 | + if (model.includes('erato')) { | |
| 572 | + return tokenizers.LLAMA3; | |
| 573 | + } | |
| 562 | 574 | return tokenizers.NONE; |
| 563 | 575 | } |
| 564 | 576 | |
| @@ -274,6 +274,9 @@ export function getTokenizerBestMatch(forApi) { | ||
| 274 | 274 | if (nai_settings.model_novel.includes('kayra')) { |
| 275 | 275 | return tokenizers.NERD2; |
| 276 | 276 | } |
| 277 | + if (nai_settings.model_novel.includes('erato')) { | |
| 278 | + return tokenizers.LLAMA3; | |
| 279 | + } | |
| 277 | 280 | } |
| 278 | 281 | if (forApi === 'kobold' || forApi === 'textgenerationwebui' || forApi === 'koboldhorde') { |
| 279 | 282 | // Try to use the API tokenizer if possible: |
| @@ -196,7 +196,7 @@ router.post('/generate', jsonParser, async function (req, res) { | ||
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | try { |
| 199 | 199 | const baseURL = (req.body.model.includes('kayra') || req.body.model.includes('erato')) ? TEXT_NOVELAI : API_NOVELAI; |
| 200 | 200 | const url = req.body.streaming ? `${baseURL}/ai/generate-stream` : `${baseURL}/ai/generate`; |
| 201 | 201 | const response = await fetch(url, { method: 'POST', timeout: 0, ...args }); |
| 202 | 202 | |