Files
NexesenexandGitHub f8b5664c18 Chores : Typos fixing round 3 (project wide, ggml dir included, comments and user facing msg only) (#2249)
* ggml: fix typos in comments across ggml/src

Corrects misspellings found in source comments (no code/logic changes):

CUDA:
- quantize.cu / quantize_id.cu: 'memroy' -> 'memory', stray 'Exchange' word in reduction comment
- fattn-mma-f16.cuh / fattn-new-mma.cu: 'synchonization' -> 'synchronization'
- fattn-new-mma.cu / fattn-vec-common.cuh: 'at lease' -> 'at least'
- fattn-vec-f32.cuh: 'Currenlty'/'dose' -> 'Currently'/'does'
- mmq_id_common.cuh: 'alays' -> 'always'
- softmax.cu: 'noncontigous' -> 'noncontiguous'

CPU / quantization:
- ggml-quants.c: 'At leat' -> 'At least'
- ggml.c: 'repeatition' -> 'repetition'

CANN:
- aclnn_ops.cpp: 'alloced' -> 'allocated', 'contigous' -> 'contiguous'
- kernels/dup.cpp: 'contigous' -> 'contiguous'

IQK:
- iqk_gemm_1bit.cpp: 'explicitely' -> 'explicitly'
- iqk_gemm_ktquants.cpp: 'nn AVX2' -> 'in AVX2'

Vulkan:
- ggml-vulkan.cpp: duplicated 'in in' -> 'in'

* ggml: fix less-common typos in comments (spellchecker pass)

Second sweep using a spell-check pass with edit-distance filtering to catch
typos missed by the common-misspelling list. Comment/comment-context fixes
only, no code changes:

- aclnn_ops.cpp: 'performace' -> 'performance'
- acl_tensor.cpp: 'shoule in' -> 'should be in'
- common.h: 'opertors'/'available' -> 'operators'/'available'
- ggml-cuda.cu: 'resepctive' -> 'respective', 'resinding' -> 'residing'
- conv2d.cu: 'ouptut_chanles' -> 'output_channels'
- scale.cu: 'Whehn' -> 'When'
- mmq_id_common.cuh: 'renameing' -> 'renaming'
- solve_tri.cu: 'supress' -> 'suppress'
- ggml-quants.c: 'ptoducts' -> 'products', 'quckly' -> 'quickly',
  'Acummulate' -> 'Accumulate'
- ggml-sycl.cpp: 'solutino'/'walkaroud' -> 'solution'/'workaround'
- ggml-vulkan.cpp: 'aross' -> 'across'
- ggml.c unified base: signficantly -> significantly (recorded in iqk too)

Also fixed duplicate word 'get get' in the quckly comments (line 14272/14488).

* Fix typo: correct hard-to-count words in comments/docs across common/examples

Spellcheckedtypos across common/, examples/, tests/ and include/ (from
typos2.txt): preserve->preserving, replacement->replacemnt,
enhance->enchance, imatrix/ima->imatrix, correct->corerct,
parameter->parmeter, utilizing->utilitizing, backward->backwrad,
manipulate->manupulate, together->togather, incomplete->parial,
sentence->dentence, retrieval->retie, prepared->prepa, partial->parial,
randomly->Randonly. Comment/prose only, no code changes.

* fixing typos (public_simplechat example)

* fixing typos (examples subdirs)
2026-08-04 07:15:28 +03:00

267 lines
8.9 KiB
JavaScript

//@ts-check
// Helpers to work with different data types
// by Humans for All
//
/**
* Given the limited context size of local LLMs and , many a times when context gets filled
* between the prompt and the response, it can lead to repeating text garbage generation.
* And many a times setting penalty wrt repetition leads to over-intelligent garbage
* repetition with slight variations. These garbage in turn can lead to overloading of the
* available model context, leading to less valuable response for subsequent prompts/queries,
* if chat history is sent to ai model.
*
* So two simple minded garbage trimming logics are experimented below.
* * one based on progressively-larger-substring-based-repeat-matching-with-partial-skip and
* * another based on char-histogram-driven garbage trimming.
* * in future characteristic of histogram over varying lengths could be used to allow for
* a more aggressive and adaptive trimming logic.
*/
/**
* Simple minded logic to help remove repeating garbage at end of the string.
* The repetition needs to be perfectly matching.
*
* The logic progressively goes on probing for longer and longer substring based
* repetition, till there is no longer repetition. In turn picks the one with
* the longest chain.
*
* @param {string} sIn
* @param {number} maxSubL
* @param {number} maxMatchLenThreshold
*/
export function trim_repeat_garbage_at_end(sIn, maxSubL=10, maxMatchLenThreshold=40) {
let rCnt = [0];
let maxMatchLen = maxSubL;
let iMML = -1;
for(let subL=1; subL < maxSubL; subL++) {
rCnt.push(0);
let i;
let refS = sIn.substring(sIn.length-subL, sIn.length);
for(i=sIn.length; i > 0; i -= subL) {
let curS = sIn.substring(i-subL, i);
if (refS != curS) {
let curMatchLen = rCnt[subL]*subL;
if (maxMatchLen < curMatchLen) {
maxMatchLen = curMatchLen;
iMML = subL;
}
break;
}
rCnt[subL] += 1;
}
}
console.debug("DBUG:DU:TrimRepeatGarbage:", rCnt);
if ((iMML == -1) || (maxMatchLen < maxMatchLenThreshold)) {
return {trimmed: false, data: sIn};
}
console.debug("DBUG:TrimRepeatGarbage:TrimmedCharLen:", maxMatchLen);
let iEnd = sIn.length - maxMatchLen;
return { trimmed: true, data: sIn.substring(0, iEnd) };
}
/**
* Simple minded logic to help remove repeating garbage at end of the string, till it cant.
* If its not able to trim, then it will try to skip a char at end and then trim, a few times.
* This ensures that even if there are multiple runs of garbage with different patterns, the
* logic still tries to munch through them.
*
* @param {string} sIn
* @param {number} maxSubL
* @param {number | undefined} [maxMatchLenThreshold]
*/
export function trim_repeat_garbage_at_end_loop(sIn, maxSubL, maxMatchLenThreshold, skipMax=16) {
let sCur = sIn;
let sSaved = "";
let iTry = 0;
while(true) {
let got = trim_repeat_garbage_at_end(sCur, maxSubL, maxMatchLenThreshold);
if (got.trimmed != true) {
if (iTry == 0) {
sSaved = got.data;
}
iTry += 1;
if (iTry >= skipMax) {
return sSaved;
}
got.data = got.data.substring(0,got.data.length-1);
} else {
iTry = 0;
}
sCur = got.data;
}
}
/**
* A simple minded try trim garbage at end using histogram driven characteristics.
* There can be variation in the repetitions, as long as no new char props up.
*
* This tracks the chars and their frequency in a specified length of substring at the end
* and in turn checks if moving further into the generated text from the end remains within
* the same char subset or goes beyond it and based on that either trims the string at the
* end or not. This allows to filter garbage at the end, including even if there are certain
* kind of small variations in the repeated text wrt position of seen chars.
*
* Allow the garbage to contain upto maxUniq chars, but at the same time ensure that
* a given type of char ie numerals or alphabets or other types dont cross the specified
* maxType limit. This allows intermixed text garbage to be identified and trimmed.
*
* ALERT: This is not perfect and only provides a rough garbage identification logic.
* Also it currently only differentiates between character classes wrt english.
*
* @param {string} sIn
* @param {number} maxType
* @param {number} maxUniq
* @param {number} maxMatchLenThreshold
*/
export function trim_hist_garbage_at_end(sIn, maxType, maxUniq, maxMatchLenThreshold) {
if (sIn.length < maxMatchLenThreshold) {
return { trimmed: false, data: sIn };
}
let iAlp = 0;
let iNum = 0;
let iOth = 0;
// Learn
let hist = {};
let iUniq = 0;
for(let i=0; i<maxMatchLenThreshold; i++) {
let c = sIn[sIn.length-1-i];
if (c in hist) {
hist[c] += 1;
} else {
if(c.match(/[0-9]/) != null) {
iNum += 1;
} else if(c.match(/[A-Za-z]/) != null) {
iAlp += 1;
} else {
iOth += 1;
}
iUniq += 1;
if (iUniq >= maxUniq) {
break;
}
hist[c] = 1;
}
}
console.debug("DBUG:TrimHistGarbage:", hist);
if ((iAlp > maxType) || (iNum > maxType) || (iOth > maxType)) {
return { trimmed: false, data: sIn };
}
// Catch and Trim
for(let i=0; i < sIn.length; i++) {
let c = sIn[sIn.length-1-i];
if (!(c in hist)) {
if (i < maxMatchLenThreshold) {
return { trimmed: false, data: sIn };
}
console.debug("DBUG:TrimHistGarbage:TrimmedCharLen:", i);
return { trimmed: true, data: sIn.substring(0, sIn.length-i+1) };
}
}
console.debug("DBUG:TrimHistGarbage:Trimmed fully");
return { trimmed: true, data: "" };
}
/**
* Keep trimming repeatedly using hist_garbage logic, till you no longer can.
* This ensures that even if there are multiple runs of garbage with different patterns,
* the logic still tries to munch through them.
*
* @param {any} sIn
* @param {number} maxType
* @param {number} maxUniq
* @param {number} maxMatchLenThreshold
*/
export function trim_hist_garbage_at_end_loop(sIn, maxType, maxUniq, maxMatchLenThreshold) {
let sCur = sIn;
while (true) {
let got = trim_hist_garbage_at_end(sCur, maxType, maxUniq, maxMatchLenThreshold);
if (!got.trimmed) {
return got.data;
}
sCur = got.data;
}
}
/**
* Try trim garbage at the end by using both the hist-driven-garbage-trimming as well as
* skip-a-bit-if-reqd-then-repeat-pattern-based-garbage-trimming, with blind retrying.
* @param {string} sIn
*/
export function trim_garbage_at_end(sIn) {
let sCur = sIn;
for(let i=0; i<2; i++) {
sCur = trim_hist_garbage_at_end_loop(sCur, 8, 24, 72);
sCur = trim_repeat_garbage_at_end_loop(sCur, 32, 72, 12);
}
return sCur;
}
/**
* NewLines array helper.
* Allow for maintaining a list of lines.
* Allow for a line to be builtup/appended part by part.
*/
export class NewLines {
constructor() {
/** @type {string[]} */
this.lines = [];
}
/**
* Extracts lines from the passed string and in turn either
* append to a previous partial line or add a new line.
* @param {string} sLines
*/
add_append(sLines) {
let aLines = sLines.split("\n");
let lCnt = 0;
for(let line of aLines) {
lCnt += 1;
// Add back newline removed if any during split
if (lCnt < aLines.length) {
line += "\n";
} else {
if (sLines.endsWith("\n")) {
line += "\n";
}
}
// Append if required
if (lCnt == 1) {
let lastLine = this.lines[this.lines.length-1];
if (lastLine != undefined) {
if (!lastLine.endsWith("\n")) {
this.lines[this.lines.length-1] += line;
continue;
}
}
}
// Add new line
this.lines.push(line);
}
}
/**
* Shift the oldest/earliest/0th line in the array. [Old-New|Earliest-Latest]
* Optionally control whether only full lines (ie those with newline at end) will be returned
* or will a partial line without a newline at end (can only be the last line) be returned.
* @param {boolean} bFullWithNewLineOnly
*/
shift(bFullWithNewLineOnly=true) {
let line = this.lines[0];
if (line == undefined) {
return undefined;
}
if ((line[line.length-1] != "\n") && bFullWithNewLineOnly){
return undefined;
}
return this.lines.shift();
}
}