"N" support for llama.cpp (#4869) * llama.cpp supports 'n' now * Fix response parsing --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -1249,7 +1249,7 @@ | ||
| 1249 | 1249 | <div class="fa-solid fa-circle-info opacity50p" title="Customize displayed samplers or add custom samplers." data-i18n="[title]Customize displayed samplers or add custom samplers."></div> |
| 1250 | 1250 | </small> |
| 1251 | 1251 | </div> |
| 1252 | 1252 | <div data-tg-type="mancer, vllm, aphrodite, tabby, infermaticai, llamacpp" data-tg-samplers="n" class="flex-container flexFlowColumn alignitemscenter flexBasis100p flexGrow flexShrink gap0"> |
| 1253 | 1253 | <small data-i18n="Multiple swipes per generation">Multiple swipes per generation</small> |
| 1254 | 1254 | <input type="number" id="n_textgenerationwebui" class="text_pole textAlignCenter" min="1" value="1" step="1" /> |
| 1255 | 1255 | </div> |
| @@ -5872,7 +5872,7 @@ export function extractMessageFromData(data, activeApi = null) { | ||
| 5872 | 5872 | case 'koboldhorde': |
| 5873 | 5873 | return data.text; |
| 5874 | 5874 | case 'textgenerationwebui': |
| 5875 | 5875 | return data.choices?.[0]?.text ?? data.choices?.[0]?.message?.content ?? data.content ?? data.response ?? data[0]?.content ?? ''; |
| 5876 | 5876 | case 'novel': |
| 5877 | 5877 | return data.output; |
| 5878 | 5878 | case 'openai': |
| @@ -5959,6 +5959,22 @@ function extractMultiSwipes(data, type) { | ||
| 5959 | 5959 | return swipes; |
| 5960 | 5960 | } |
| 5961 | 5961 | |
| 5962 | + if (main_api === 'textgenerationwebui' && textgen_settings.type === textgen_types.LLAMACPP) { | |
| 5963 | + if (!Array.isArray(data)) { | |
| 5964 | + return swipes; | |
| 5965 | + } | |
| 5966 | + | |
| 5967 | + const multiSwipeCount = data.length - 1; | |
| 5968 | + if (multiSwipeCount <= 0) { | |
| 5969 | + return swipes; | |
| 5970 | + } | |
| 5971 | + | |
| 5972 | + for (let i = 1; i < data.length; i++) { | |
| 5973 | + const text = data?.[i]?.content ?? ''; | |
| 5974 | + swipes.push(text); | |
| 5975 | + } | |
| 5976 | + } | |
| 5977 | + | |
| 5962 | 5978 | if (main_api === 'openai' || (main_api === 'textgenerationwebui' && [textgen_types.MANCER, textgen_types.VLLM, textgen_types.APHRODITE, textgen_types.TABBY, textgen_types.INFERMATICAI].includes(textgen_settings.type))) { |
| 5963 | 5979 | if (!Array.isArray(data.choices)) { |
| 5964 | 5980 | return swipes; |
| @@ -5972,18 +5988,18 @@ function extractMultiSwipes(data, type) { | ||
| 5972 | 5988 | |
| 5973 | 5989 | for (let i = 1; i < data.choices.length; i++) { |
| 5974 | 5990 | const text = data?.choices[i]?.message?.content ?? data?.choices[i]?.text ?? ''; |
| 5975 | - const cleanedText = cleanUpMessage({ | |
| 5991 | + swipes.push(text); | |
| 5992 | + } | |
| 5993 | + } | |
| 5994 | + | |
| 5995 | + const cleanedSwipes = swipes.map(text => cleanUpMessage({ | |
| 5976 | 5996 | getMessage: text, |
| 5977 | 5997 | isImpersonate: false, |
| 5978 | 5998 | isContinue: false, |
| 5979 | 5999 | displayIncompleteSentences: false, |
| 5980 | 6000 | })); |
| 5981 | - | |
| 5982 | - swipes.push(cleanedText); | |
| 5983 | - } | |
| 5984 | - } | |
| 5985 | 6001 | |
| 5986 | 6002 | return swipescleanedSwipes; |
| 5987 | 6003 | } |
| 5988 | 6004 | |
| 5989 | 6005 | /** |
| @@ -1,6 +1,9 @@ | ||
| 1 | 1 | import { power_user } from './power-user.js'; |
| 2 | 2 | import { delay } from './utils.js'; |
| 3 | 3 | |
| 4 | +// Symbol for not primary swipe error | |
| 5 | +const NOT_PRIMARY = Symbol('not_primary_swipe'); | |
| 6 | + | |
| 4 | 7 | /** |
| 5 | 8 | * A stream which handles Server-Sent Events from a binary ReadableStream like you get from the fetch API. |
| 6 | 9 | */ |
| @@ -198,6 +201,10 @@ async function* parseStreamData(json) { | ||
| 198 | 201 | } |
| 199 | 202 | // llama.cpp? |
| 200 | 203 | else if (typeof json.content === 'string' && json.content.length > 0 && json.object !== 'chat.completion.chunk') { |
| 204 | + const isNotPrimary = json?.index > 0; | |
| 205 | + if (isNotPrimary) { | |
| 206 | + throw new Error('Not a primary swipe', { cause: NOT_PRIMARY }); | |
| 207 | + } | |
| 201 | 208 | for (let i = 0; i < json.content.length; i++) { |
| 202 | 209 | const str = json.content[i]; |
| 203 | 210 | yield { |
| @@ -211,7 +218,7 @@ async function* parseStreamData(json) { | ||
| 211 | 218 | else if (Array.isArray(json.choices)) { |
| 212 | 219 | const isNotPrimary = json?.choices?.[0]?.index > 0; |
| 213 | 220 | if (isNotPrimary || json.choices.length === 0) { |
| 214 | 221 | throw new Error('Not a primary swipe', { cause: NOT_PRIMARY }); |
| 215 | 222 | } |
| 216 | 223 | |
| 217 | 224 | if (typeof json.choices[0].text === 'string' && json.choices[0].text.length > 0) { |
| @@ -357,7 +364,9 @@ export class SmoothEventSourceStream extends EventSourceStream { | ||
| 357 | 364 | lastStr = parsed.chunk; |
| 358 | 365 | } |
| 359 | 366 | } catch (error) { |
| 367 | + if (error instanceof Error && error.cause !== NOT_PRIMARY) { | |
| 360 | 368 | console.debug('Smooth Streaming parsing error', error); |
| 369 | + } | |
| 361 | 370 | controller.enqueue(event); |
| 362 | 371 | } |
| 363 | 372 | }, |
| @@ -1284,6 +1284,10 @@ export async function generateTextGenWithStreaming(generate_data, signal) { | ||
| 1284 | 1284 | if (data?.choices?.[0]?.index > 0) { |
| 1285 | 1285 | const swipeIndex = data.choices[0].index - 1; |
| 1286 | 1286 | swipes[swipeIndex] = (swipes[swipeIndex] || '') + data.choices[0].text; |
| 1287 | + } else if (data?.index > 0) { | |
| 1288 | + // llama.cpp streaming swipe | |
| 1289 | + const swipeIndex = data.index - 1; | |
| 1290 | + swipes[swipeIndex] = (swipes[swipeIndex] || '') + data.content; | |
| 1287 | 1291 | } else { |
| 1288 | 1292 | const newText = data?.choices?.[0]?.text || data?.content || ''; |
| 1289 | 1293 | text += newText; |
| @@ -1724,7 +1728,7 @@ export function createTextGenGenerationData(settings, model, finalPrompt = null, | ||
| 1724 | 1728 | params.dry_sequence_breakers = params.parseSequenceBreakers(); |
| 1725 | 1729 | } |
| 1726 | 1730 | |
| 1727 | 1731 | if (settings.type === TABBY || settings.type === LLAMACPP) { |
| 1728 | 1732 | params.n = canMultiSwipe ? settings.n : 1; |
| 1729 | 1733 | } |
| 1730 | 1734 | |