Quellcode-Bibliothek wllama-module.mjs
Sprache: unbekannt
|
|
Untersuchungsergebnis.mjs Download desUnknown {[0] [0] [0]}
var O={erro_evt:{name:"erro_evt",structName:"glue_msg_error",className:"GlueMsgEr ror",fields:[{type:"str",name:"message",isNullable:!1}]},load_req:{name:"load_req",structName:"glue_msg_load_req",className:"GlueMsgLoadReq",fields:[{type:"arr_str",name:"model_paths",isNullable:!1},{type:"bool",name:"n_ctx_auto",isNullable:!1},{type:"bool",name:"use_mmap",isNullable:!1},{type:"bool",name:"use_mlock",isNullable:!1},{type:"int",name:"n_gpu_layers",isNullable:!1},{type:"int",name:"seed",isNullable:!1},{type:"int",name:"n_ctx",isNullable:!1},{type:"int",name:"n_threads",isNullable:!1},{type:"bool",name:"embeddings",isNullable:!0},{type:"bool",name:"offload_kqv",isNullable:!0},{type:"int",name:"n_batch",isNullable:!0},{type:"int",name:"n_seq_max",isNullable:!0},{type:"str",name:"pooling_type",isNullable:!0},{type:"str",name:"rope_scaling_type",isNullable:!0},{type:"float",name:"rope_freq_base",isNullable:!0},{type:"float",name:"rope_freq_scale",isNullable:!0},{type:"float",name:"yarn_ext_factor",isNullable:!0},{type:"float",name:"yarn_attn_factor",isNullable:!0},{type:"float",name:"yarn_beta_fast",isNullable:!0},{type:"float",name:"yarn_beta_slow",isNullable:!0},{type:"int",name:"yarn_orig_ctx",isNullable:!0},{type:"str",name:"cache_type_k",isNullable:!0},{type:"str",name:"cache_type_v",isNullable:!0},{type:"int",name:"n_ubatch",isNullable:!0},{type:"bool",name:"flash_attn",isNullable:!0},{type:"int",name:"n_threads_decoding",isNullable:!0}]},load_res:{name:"load_res",structName:"glue_msg_load_res",className:"GlueMsgLoadRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"int",name:"n_ctx",isNullable:!1},{type:"int",name:"n_batch",isNullable:!1},{type:"int",name:"n_ubatch",isNullable:!1},{type:"int",name:"n_vocab",isNullable:!1},{type:"int",name:"n_ctx_train",isNullable:!1},{type:"int",name:"n_embd",isNullable:!1},{type:"int",name:"n_layer",isNullable:!1},{type:"arr_str",name:"metadata_key",isNullable:!1},{type:"arr_str",name:"metadata_val",isNullable:!1},{type:"int",name:"token_bos",isNullable:!1},{type:"int",name:"token_eos",isNullable:!1},{type:"int",name:"token_eot",isNullable:!1},{type:"arr_int",name:"list_tokens_eog",isNullable:!1},{type:"bool",name:"add_bos_token",isNullable:!1},{type:"bool",name:"add_eos_token",isNullable:!1},{type:"bool",name:"has_encoder",isNullable:!1},{type:"int",name:"token_decoder_start",isNullable:!1}]},opti_req:{name:"opti_req",structName:"glue_msg_set_options_req",className:"GlueMsgSetOptionsReq",fields:[{type:"bool",name:"embeddings",isNullable:!1}]},opti_res:{name:"opti_res",structName:"glue_msg_set_options_res",className:"GlueMsgSetOptionsRes",fields:[{type:"bool",name:"success",isNullable:!1}]},sint_req:{name:"sint_req",structName:"glue_msg_sampling_init_req",className:"GlueMsgSamplingInitReq",fields:[{type:"int",name:"mirostat",isNullable:!0},{type:"float",name:"mirostat_tau",isNullable:!0},{type:"float",name:"mirostat_eta",isNullable:!0},{type:"float",name:"temp",isNullable:!0},{type:"float",name:"top_p",isNullable:!0},{type:"int",name:"top_k",isNullable:!0},{type:"int",name:"penalty_last_n",isNullable:!0},{type:"float",name:"penalty_repeat",isNullable:!0},{type:"float",name:"penalty_freq",isNullable:!0},{type:"float",name:"penalty_present",isNullable:!0},{type:"float",name:"dynatemp_range",isNullable:!0},{type:"float",name:"dynatemp_exponent",isNullable:!0},{type:"arr_str",name:"samplers_sequence",isNullable:!0},{type:"str",name:"grammar",isNullable:!0},{type:"int",name:"n_prev",isNullable:!0},{type:"int",name:"n_probs",isNullable:!0},{type:"float",name:"min_p",isNullable:!0},{type:"float",name:"typical_p",isNullable:!0},{type:"float",name:"typ_p",isNullable:!0},{type:"arr_int",name:"logit_bias_toks",isNullable:!0},{type:"arr_float",name:"logit_bias_vals",isNullable:!0},{type:"arr_int",name:"tokens",isNullable:!0}]},sint_res:{name:"sint_res",structName:"glue_msg_sampling_init_res",className:"GlueMsgSamplingInitRes",fields:[{type:"bool",name:"success",isNullable:!1}]},gvoc_req:{name:"gvoc_req",structName:"glue_msg_get_vocab_req",className:"GlueMsgGetVocabReq",fields:[]},gvoc_res:{name:"gvoc_res",structName:"glue_msg_get_vocab_res",className:"GlueMsgGetVocabRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"arr_raw",name:"vocab",isNullable:!1}]},lkup_req:{name:"lkup_req",structName:"glue_msg_lookup_token_req",className:"GlueMsgLookupTokenReq",fields:[{type:"str",name:"piece",isNullable:!1}]},lkup_res:{name:"lkup_res",structName:"glue_msg_lookup_token_res",className:"GlueMsgLookupTokenRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"int",name:"token",isNullable:!1}]},tokn_req:{name:"tokn_req",structName:"glue_msg_tokenize_req",className:"GlueMsgTokenizeReq",fields:[{type:"str",name:"text",isNullable:!1},{type:"bool",name:"special",isNullable:!1}]},tokn_res:{name:"tokn_res",structName:"glue_msg_tokenize_res",className:"GlueMsgTokenizeRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"arr_int",name:"tokens",isNullable:!1}]},dtkn_req:{name:"dtkn_req",structName:"glue_msg_detokenize_req",className:"GlueMsgDetokenizeReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1}]},dtkn_res:{name:"dtkn_res",structName:"glue_msg_detokenize_res",className:"GlueMsgDetokenizeRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"raw",name:"buffer",isNullable:!1}]},deco_req:{name:"deco_req",structName:"glue_msg_decode_req",className:"GlueMsgDecodeReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1},{type:"bool",name:"skip_logits",isNullable:!1}]},deco_res:{name:"deco_res",structName:"glue_msg_decode_res",className:"GlueMsgDecodeRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"int",name:"n_past",isNullable:!1}]},enco_req:{name:"enco_req",structName:"glue_msg_encode_req",className:"GlueMsgEncodeReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1}]},enco_res:{name:"enco_res",structName:"glue_msg_encode_res",className:"GlueMsgEncodeRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"int",name:"n_past",isNullable:!1}]},ssam_req:{name:"ssam_req",structName:"glue_msg_sampling_sample_req",className:"GlueMsgSamplingSampleReq",fields:[]},ssam_res:{name:"ssam_res",structName:"glue_msg_sampling_sample_res",className:"GlueMsgSamplingSampleRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"raw",name:"piece",isNullable:!1},{type:"int",name:"token",isNullable:!1}]},sacc_req:{name:"sacc_req",structName:"glue_msg_sampling_accept_req",className:"GlueMsgSamplingAcceptReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1}]},sacc_res:{name:"sacc_res",structName:"glue_msg_sampling_accept_res",className:"GlueMsgSamplingAcceptRes",fields:[{type:"bool",name:"success",isNullable:!1}]},glog_req:{name:"glog_req",structName:"glue_msg_get_logits_req",className:"GlueMsgGetLogitsReq",fields:[{type:"int",name:"top_k",isNullable:!1}]},glog_res:{name:"glog_res",structName:"glue_msg_get_logits_res",className:"GlueMsgGetLogitsRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"arr_int",name:"tokens",isNullable:!1},{type:"arr_float",name:"probs",isNullable:!1}]},gemb_req:{name:"gemb_req",structName:"glue_msg_get_embeddings_req",className:"GlueMsgGetEmbeddingsReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1}]},gemb_res:{name:"gemb_res",structName:"glue_msg_get_embeddings_res",className:"GlueMsgGetEmbeddingsRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"arr_float",name:"embeddings",isNullable:!1}]},kvcr_req:{name:"kvcr_req",structName:"glue_msg_get_kv_remove_req",className:"GlueMsgGetKvRemoveReq",fields:[{type:"int",name:"n_keep",isNullable:!1},{type:"int",name:"n_discard",isNullable:!1}]},kvcr_res:{name:"kvcr_res",structName:"glue_msg_get_kv_remove_res",className:"GlueMsgGetKvRemoveRes",fields:[{type:"int",name:"n_past",isNullable:!1},{type:"bool",name:"success",isNullable:!1}]},kvcc_req:{name:"kvcc_req",structName:"glue_msg_get_kv_clear_req",className:"GlueMsgGetKvClearReq",fields:[]},kvcc_res:{name:"kvcc_res",structName:"glue_msg_get_kv_clear_res",className:"GlueMsgGetKvClearRes",fields:[{type:"int",name:"n_past",isNullable:!1},{type:"bool",name:"success",isNullable:!1}]},sesa_req:{name:"sesa_req",structName:"glue_msg_session_save_req",className:"GlueMsgSessionSaveReq",fields:[{type:"str",name:"session_path",isNullable:!1}]},sesa_res:{name:"sesa_res",structName:"glue_msg_session_save_res",className:"GlueMsgSessionSaveRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"arr_int",name:"tokens",isNullable:!1}]},sesl_req:{name:"sesl_req",structName:"glue_msg_session_load_req",className:"GlueMsgSessionLoadReq",fields:[{type:"str",name:"session_path",isNullable:!1},{type:"arr_int",name:"tokens",isNullable:!1}]},sesl_res:{name:"sesl_res",structName:"glue_msg_session_load_res",className:"GlueMsgSessionLoadRes",fields:[{type:"bool",name:"success",isNullable:!1}]},stat_req:{name:"stat_req",structName:"glue_msg_status_req",className:"GlueMsgStatusReq",fields:[]},stat_res:{name:"stat_res",structName:"glue_msg_status_res",className:"GlueMsgStatusRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"arr_int",name:"tokens",isNullable:!1}]},tben_req:{name:"tben_req",structName:"glue_msg_test_benchmark_req",className:"GlueMsgTestBenchmarkReq",fields:[{type:"str",name:"type",isNullable:!1},{type:"int",name:"n_samples",isNullable:!1}]},tben_res:{name:"tben_res",structName:"glue_msg_test_benchmark_res",className:"GlueMsgTestBenchmarkRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"int",name:"t_ms",isNullable:!1}]},tper_req:{name:"tper_req",structName:"glue_msg_test_perplexity_req",className:"GlueMsgTestPerplexityReq",fields:[{type:"arr_int",name:"tokens",isNullable:!1}]},tper_res:{name:"tper_res",structName:"glue_msg_test_perplexity_res",className:"GlueMsgTestPerplexityRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"float",name:"ppl",isNullable:!1},{type:"float",name:"nll",isNullable:!1},{type:"float",name:"cross_entropy",isNullable:!1},{type:"int",name:"n_tokens",isNullable:!1},{type:"int",name:"t_ms",isNullable:!1}]},cfmt_req:{name:"cfmt_req",structName:"glue_msg_chat_format_req",className:"GlueMsgChatFormatReq",fields:[{type:"str",name:"tmpl",isNullable:!0},{type:"bool",name:"add_ass",isNullable:!0},{type:"arr_str",name:"roles",isNullable:!1},{type:"arr_str",name:"contents",isNullable:!1}]},cfmt_res:{name:"cfmt_res",structName:"glue_msg_chat_format_res",className:"GlueMsgChatFormatRes",fields:[{type:"bool",name:"success",isNullable:!1},{type:"str",name:"message",isNullable:!1},{type:"str",name:"formatted_chat",isNullable:!1}]}};var E=new Uint8Array([71,76,85,69]),L=0,ne=1,oe=2,se=3,ie=4,le=5,de=6,ue=7,me=8,ce=9,pe=10,U={str:ie,int:oe,float:se,bool:ne,raw:le,arr_str:ce,arr_int:ue,arr_float:me,arr_bool:de,arr_raw:pe,null:L};function W(o){let e=0,r=new DataView(o.buffer),t=()=>{let p=r.getUint32(e,!0);return e+=4,p},a=()=>{let p=r.getInt32(e,!0);return e+=4,p},n=()=>{let p=r.getFloat32(e,!0);return e+=4,p},s=()=>t()!==0,l=p=>{let g=p??t(),k=new TextDecoder().decode(o.slice(e,e+g));return e+=g,k},u=()=>{let p=t(),g=o.slice(e,e+p);return e+=p,g},i=p=>{let g=t(),k=new Array(g);for(let C=0;C<g;C++)k[C]=p();return k},_=()=>null,w=p=>{switch(p.type){case"str":return l();case"int":return a();case"float":return n();case"bool":return s();case"raw":return u();case"arr_str":return i(l);case"arr_int":return i(a);case"arr_float":return i(n);case"arr_bool":return i(s);case"arr_raw":return i(u);case"null":return _()}},f=o[0]===E[0]&&o[1]===E[1]&&o[2]===E[2]&&o[3]===E[3];if(e+=4,!f)throw new Error("Invalid magic number");if(t()!==1)throw new Error("Invalid version number");let d=l(8),m=O[d];if(!m)throw new Error(`Unknown message name: ${d}`);let F={_name:d};for(let p of m.fields){let g=t();if(g===L){if(!p.isNullable)throw new Error(`${d}: Expect field ${p.name} to be non-nullable`);F[p.name]=null;continue}if(g!==U[p.type])throw new Error(`${d}: Expect field ${p.name} to have type ${p.type}`);F[p.name]=w(p)}return F}function q(o){let e=O[o._name];if(!e)throw new Error(`Unknown message name: ${o._name}`);let r=[],t=d=>{let m=new ArrayBuffer(4);new DataView(m).setUint32(0,d,!0),r.push(new Uint8Array(m))},a=d=>{let m=new ArrayBuffer(4);new DataView(m).setInt32(0,d,!0),r.push(new Uint8Array(m))},n=d=>{let m=new ArrayBuffer(4);new DataView(m).setFloat32(0,d,!0),r.push(new Uint8Array(m))},s=d=>{t(d?1:0)},l=d=>{let m=new TextEncoder().encode(d);t(m.byteLength),r.push(m)},u=d=>{t(d.byteLength),r.push(d)},i=(d,m)=>{t(d.length);for(let F of d)m(F)},_=()=>{};r.push(E),t(1);{let d=new TextEncoder().encode(o._name);r.push(d)}for(let d of e.fields){let m=o[d.name];if(!d.isNullable&&m==null)throw new Error(`${o._name}: Expect field ${d.name} to be non-nullable`);if(m==null){t(L);continue}switch(t(U[d.type]),d.type){case"str":l(m);break;case"int":a(m);break;case"float":n(m);break;case"bool":s(m);break;case"raw":u(m);break;case"arr_str":i(m,l);break;case"arr_int":i(m,a);break;case"arr_float":i(m,n);break;case"arr_bool":i(m,s);break;case"arr_raw":i(m,u);break;case"null":_();break}}let w=r.reduce((d,m)=>d+m.byteLength,0),f=new Uint8Array(w),h=0;for(let d of r)f.set(d,h),h+=d.byteLength;return f}var Y=o=>{let e=o.reduce((t,a)=>t+a.length,0),r=new Uint8Array(e);r.set(o[0],0);for(let t=1;t<o.length;t++)r.set(o[t],o[t-1].length);return r},fe=new TextDecoder,A=o=>fe.decode(o);var j=/-(\d{5})-of-(\d{5})\.gguf$/,V=o=>{let e=o.match(j);return e?{baseURL:o.replace(j,""),current:parseInt(e[1]),total:parseInt(e[2])}:{baseURL:o,current:1,total:1}};var $=o=>{o.every(r=>!!r.name)&&o.length>1&&o.sort((t,a)=>{let n=V(t.name),s=V(a.name);return n.current-s.current})};var D=o=>o;var T=o=>o.reduce((e,r)=>e+r,0),H=o=>!!o?.startsWith,K=()=>(async o=>{try{return typeof MessageChannel<"u"&&new MessageChannel().port1.postMessage(new SharedArrayBuffer(1)),WebAssembly.validate(o)}catch{return!1}})(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,5,4,1,3,1,1,10,11,1,9,0,65,0,254,16,2,0,26,11])),_e=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,10,8,1,6,0,6,64,25,11,11])),he=async()=>WebAssembly.validate(new Uint8Array([0,97,115,109,1,0,0,0,1,5,1,96,0,1,123,3,2,1,0,10,10,1,8,0,65,0,253,15,253,98,11])),X=async()=>{if(!await _e())throw new Error("WebAssembly runtime does not support exception handling");if(!await he())throw new Error("WebAssembly runtime does not support SIMD")};var P=()=>!!navigator.userAgent.match(/Version\/([0-9\._]+).*Mobile.*Safari.*/),M=o=>{let e=URL.createObjectURL(H(o)?new Blob([o],{type:"text/javascript"}):o);return new Worker(e,{type:"module"})},J=o=>(...e)=>{let r=[],t;return r.push(new Promise(a=>{t=a})),o(...e,(a,n)=>{t([a,n]),r.push(new Promise(s=>{t=s}))}),async function*(){let a;for(let n=0,s=!1;!s;n++)[a,s]=await r[n],delete r[n],a!==void 0&&(yield a)}()};var Z=`// Start the main llama.cpp
let wllamaMalloc;
let wllamaStart;
let wllamaAction;
let wllamaExit;
let wllamaDebug;
let Module = null;
//////////////////////////////////////////////////////////////
// UTILS
//////////////////////////////////////////////////////////////
// send message back to main thread
const msg = (data, transfer) => postMessage(data, transfer);
// Convert CPP log into JS log
const cppLogToJSLog = (line) => {
const matched = line.match(/@@(DEBUG|INFO|WARN|ERROR)@@(.*)/);
return !!matched
? {
level: (matched[1] === 'INFO' ? 'debug' : matched[1]).toLowerCase(),
text: matched[2],
}
: { level: 'log', text: line };
};
// Get module config that forwards stdout/err to main thread
const getWModuleConfig = (_argMainScriptBlob) => {
var pathConfig = RUN_OPTIONS.pathConfig;
var pthreadPoolSize = RUN_OPTIONS.nbThread;
var argMainScriptBlob = _argMainScriptBlob;
if (!pathConfig['wllama.wasm']) {
throw new Error('"wllama.wasm" is missing in pathConfig');
}
return {
noInitialRun: true,
print: function (text) {
if (arguments.length > 1)
text = Array.prototype.slice.call(arguments).join(' ');
msg({ verb: 'console.log', args: [text] });
},
printErr: function (text) {
if (arguments.length > 1)
text = Array.prototype.slice.call(arguments).join(' ');
const logLine = cppLogToJSLog(text);
msg({ verb: 'console.' + logLine.level, args: [logLine.text] });
},
locateFile: function (filename, basePath) {
const p = pathConfig[filename];
const truncate = (str) =>
str.length > 128 ? \`\${str.substr(0, 128)}...\` : str;
if (filename.match(/wllama\\.worker\\.js/)) {
msg({
verb: 'console.error',
args: [
'"wllama.worker.js" is removed from v2.2.1. Hint: make sure to clear browser\\'s cache.',
],
});
} else {
msg({
verb: 'console.debug',
args: [\`Loading "\${filename}" from "\${truncate(p)}"\`],
});
return p;
}
},
mainScriptUrlOrBlob: argMainScriptBlob,
pthreadPoolSize,
wasmMemory: pthreadPoolSize > 1 ? getWasmMemory() : null,
onAbort: function (text) {
msg({ verb: 'signal.abort', args: [text] });
},
};
};
// Get the memory to be used by wasm. (Only used in multi-thread mode)
// Because we have a weird OOM issue on iOS, we need to try some values
// See: https://github.com/emscripten-core/emscripten/issues/19144
// https://github.com/godotengine/godot/issues/70621
const getWasmMemory = () => {
let minBytes = 128 * 1024 * 1024;
let maxBytes = 4096 * 1024 * 1024;
let stepBytes = 128 * 1024 * 1024;
while (maxBytes > minBytes) {
try {
const wasmMemory = new WebAssembly.Memory({
initial: minBytes / 65536,
maximum: maxBytes / 65536,
shared: true,
});
return wasmMemory;
} catch (e) {
maxBytes -= stepBytes;
continue; // retry
}
}
throw new Error('Cannot allocate WebAssembly.Memory');
};
//////////////////////////////////////////////////////////////
// MEMFS PATCH
//////////////////////////////////////////////////////////////
/**
* By default, emscripten uses memfs. The way it works is by
* allocating new Uint8Array in javascript heap. This is not good
* because it requires files to be copied to wasm heap each time
* a file is read.
*
* HeapFS is an alternative, which resolves this problem by
* allocating space for file directly inside wasm heap. This
* allows us to mmap without doing any copy.
*
* For llama.cpp, this is great because we use MAP_SHARED
*
* Ref: https://github.com/ngxson/wllama/pull/39
* Ref: https://github.com/emscripten-core/emscripten/blob/main/src/library_memfs.js
*
* Note 29/05/2024 @ngxson
* Due to ftell() being limited to MAX_LONG, we cannot load files bigger than 2^31 bytes (or 2GB)
* Ref: https://github.com/emscripten-core/emscripten/blob/main/system/lib/libc/musl/src/stdio/ftell.c
*/
const fsNameToFile = {}; // map Name => File
const fsIdToFile = {}; // map ID => File
let currFileId = 0;
// Patch and redirect memfs calls to wllama
const patchMEMFS = () => {
const m = Module;
// save functions
m.MEMFS.stream_ops._read = m.MEMFS.stream_ops.read;
m.MEMFS.stream_ops._write = m.MEMFS.stream_ops.write;
m.MEMFS.stream_ops._llseek = m.MEMFS.stream_ops.llseek;
m.MEMFS.stream_ops._allocate = m.MEMFS.stream_ops.allocate;
m.MEMFS.stream_ops._mmap = m.MEMFS.stream_ops.mmap;
m.MEMFS.stream_ops._msync = m.MEMFS.stream_ops.msync;
const patchStream = (stream) => {
const name = stream.node.name;
if (fsNameToFile[name]) {
const f = fsNameToFile[name];
stream.node.contents = m.HEAPU8.subarray(f.ptr, f.ptr + f.size);
stream.node.usedBytes = f.size;
}
};
// replace "read" functions
m.MEMFS.stream_ops.read = function (
stream,
buffer,
offset,
length,
position
) {
patchStream(stream);
return m.MEMFS.stream_ops._read(stream, buffer, offset, length, position);
};
m.MEMFS.ops_table.file.stream.read = m.MEMFS.stream_ops.read;
// replace "llseek" functions
m.MEMFS.stream_ops.llseek = function (stream, offset, whence) {
patchStream(stream);
return m.MEMFS.stream_ops._llseek(stream, offset, whence);
};
m.MEMFS.ops_table.file.stream.llseek = m.MEMFS.stream_ops.llseek;
// replace "mmap" functions
m.MEMFS.stream_ops.mmap = function (stream, length, position, prot, flags) {
patchStream(stream);
const name = stream.node.name;
if (fsNameToFile[name]) {
const f = fsNameToFile[name];
return {
ptr: f.ptr + position,
allocated: false,
};
} else {
return m.MEMFS.stream_ops._mmap(stream, length, position, prot, flags);
}
};
m.MEMFS.ops_table.file.stream.mmap = m.MEMFS.stream_ops.mmap;
// mount FS
m.FS.mkdir('/models');
m.FS.mount(m.MEMFS, { root: '.' }, '/models');
};
// Allocate a new file in wllama heapfs, returns file ID
const heapfsAlloc = (name, size) => {
if (size < 1) {
throw new Error('File size must be bigger than 0');
}
const m = Module;
const ptr = m.mmapAlloc(size);
const file = {
ptr: ptr,
size: size,
id: currFileId++,
};
fsIdToFile[file.id] = file;
fsNameToFile[name] = file;
return file.id;
};
// Add new file to wllama heapfs, return number of written bytes
const heapfsWrite = (id, buffer, offset) => {
const m = Module;
if (fsIdToFile[id]) {
const { ptr, size } = fsIdToFile[id];
const afterWriteByte = offset + buffer.byteLength;
if (afterWriteByte > size) {
throw new Error(
\`File ID \${id} write out of bound, afterWriteByte = \${afterWriteByte} while size = \${size}\`
);
}
m.HEAPU8.set(buffer, ptr + offset);
return buffer.byteLength;
} else {
throw new Error(\`File ID \${id} not found in heapfs\`);
}
};
//////////////////////////////////////////////////////////////
// MAIN CODE
//////////////////////////////////////////////////////////////
const callWrapper = (name, ret, args) => {
const fn = Module.cwrap(name, ret, args);
return async (action, req) => {
let result;
try {
if (args.length === 2) {
result = await fn(action, req);
} else {
result = fn();
}
} catch (ex) {
console.error(ex);
throw ex;
}
return result;
};
};
onmessage = async (e) => {
if (!e.data) return;
const { verb, args, callbackId } = e.data;
if (!callbackId) {
msg({ verb: 'console.error', args: ['callbackId is required', e.data] });
return;
}
if (verb === 'module.init') {
const argMainScriptBlob = args[0];
try {
Module = getWModuleConfig(argMainScriptBlob);
Module.onRuntimeInitialized = () => {
// async call once module is ready
// init FS
patchMEMFS();
// init cwrap
const pointer = 'number';
// TODO: note sure why emscripten cannot bind if there is only 1 argument
wllamaMalloc = callWrapper('wllama_malloc', pointer, [
'number',
pointer,
]);
wllamaStart = callWrapper('wllama_start', 'string', []);
wllamaAction = callWrapper('wllama_action', pointer, [
'string',
pointer,
]);
wllamaExit = callWrapper('wllama_exit', 'string', []);
wllamaDebug = callWrapper('wllama_debug', 'string', []);
msg({ callbackId, result: null });
};
wModuleInit();
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'fs.alloc') {
const argFilename = args[0];
const argSize = args[1];
try {
// create blank file
const emptyBuffer = new ArrayBuffer(0);
Module['FS_createDataFile'](
'/models',
argFilename,
emptyBuffer,
true,
true,
true
);
// alloc data on heap
const fileId = heapfsAlloc(argFilename, argSize);
msg({ callbackId, result: { fileId } });
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'fs.write') {
const argFileId = args[0];
const argBuffer = args[1];
const argOffset = args[2];
try {
const writtenBytes = heapfsWrite(argFileId, argBuffer, argOffset);
msg({ callbackId, result: { writtenBytes } });
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'wllama.start') {
try {
const result = await wllamaStart();
msg({ callbackId, result });
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'wllama.action') {
const argAction = args[0];
const argEncodedMsg = args[1];
try {
const inputPtr = await wllamaMalloc(argEncodedMsg.byteLength, 0);
// copy data to wasm heap
const inputBuffer = new Uint8Array(
Module.HEAPU8.buffer,
inputPtr,
argEncodedMsg.byteLength
);
inputBuffer.set(argEncodedMsg, 0);
const outputPtr = await wllamaAction(argAction, inputPtr);
// length of output buffer is written at the first 4 bytes of input buffer
const outputLen = new Uint32Array(Module.HEAPU8.buffer, inputPtr, 1)[0];
// copy the output buffer to JS heap
const outputBuffer = new Uint8Array(outputLen);
const outputSrcView = new Uint8Array(
Module.HEAPU8.buffer,
outputPtr,
outputLen
);
outputBuffer.set(outputSrcView, 0); // copy it
msg({ callbackId, result: outputBuffer }, [outputBuffer.buffer]);
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'wllama.exit') {
try {
const result = await wllamaExit();
msg({ callbackId, result });
} catch (err) {
msg({ callbackId, err });
}
return;
}
if (verb === 'wllama.debug') {
try {
const result = await wllamaDebug();
msg({ callbackId, result });
} catch (err) {
msg({ callbackId, err });
}
return;
}
};
`,z=`let accessHandle;
let abortController = new AbortController();
async function openFile(filename) {
const opfsRoot = await navigator.storage.getDirectory();
const cacheDir = await opfsRoot.getDirectoryHandle('cache', { create: true });
const fileHandler = await cacheDir.getFileHandle(filename, { create: true });
accessHandle = await fileHandler.createSyncAccessHandle();
accessHandle.truncate(0); // clear file content
}
async function writeFile(buf) {
accessHandle.write(buf);
}
async function closeFile() {
accessHandle.flush();
accessHandle.close();
}
async function writeTextFile(filename, str) {
await openFile(filename);
await writeFile(new TextEncoder().encode(str));
await closeFile();
}
const throttled = (func, delay) => {
let lastRun = 0;
return (...args) => {
const now = Date.now();
if (now - lastRun > delay) {
lastRun = now;
func.apply(null, args);
}
};
};
const assertNonNull = (val) => {
if (val === null || val === undefined) {
throw new Error('OPFS Worker: Assertion failed');
}
};
// respond to main thread
const resOK = () => postMessage({ ok: true });
const resProgress = (loaded, total) =>
postMessage({ progress: { loaded, total } });
const resErr = (err) => postMessage({ err });
onmessage = async (e) => {
try {
if (!e.data) return;
/**
* @param {Object} e.data
*
* Fine-control FS actions:
* - { action: 'open', filename: 'string' }
* - { action: 'write', buf: ArrayBuffer }
* - { action: 'close' }
*
* Simple write API:
* - { action: 'write-simple', filename: 'string', buf: ArrayBuffer }
*
* Download API:
* - { action: 'download', url: 'string', filename: 'string', options: Object, metadataFileName: 'string' }
* - { action: 'download-abort' }
*/
const { action, filename, buf, url, options, metadataFileName } = e.data;
if (action === 'open') {
assertNonNull(filename);
await openFile(filename);
return resOK();
} else if (action === 'write') {
assertNonNull(buf);
await writeFile(buf);
return resOK();
} else if (action === 'close') {
await closeFile();
return resOK();
} else if (action === 'write-simple') {
assertNonNull(filename);
assertNonNull(buf);
await openFile(filename);
await writeFile(buf);
await closeFile();
return resOK();
} else if (action === 'download') {
assertNonNull(url);
assertNonNull(filename);
assertNonNull(metadataFileName);
assertNonNull(options);
assertNonNull(options.aborted);
abortController = new AbortController();
if (options.aborted) abortController.abort();
const response = await fetch(url, {
...options,
signal: abortController.signal,
});
const contentLength = response.headers.get('content-length');
const etag = (response.headers.get('etag') || '').replace(
/[^A-Za-z0-9]/g,
''
);
const total = parseInt(contentLength, 10);
const reader = response.body.getReader();
await openFile(filename);
let loaded = 0;
const throttledProgress = throttled(resProgress, 100);
while (true) {
const { done, value } = await reader.read();
if (done) break;
loaded += value.byteLength;
await writeFile(value);
throttledProgress(loaded, total);
}
resProgress(total, total); // 100% done
await closeFile();
// make sure this is in-sync with CacheEntryMetadata
await writeTextFile(
metadataFileName,
JSON.stringify({
originalURL: url,
originalSize: total,
etag,
})
);
return resOK();
} else if (action === 'download-abort') {
if (abortController) {
abortController.abort();
}
return;
}
throw new Error('OPFS Worker: Invalid action', e.data);
} catch (err) {
return resErr(err);
}
};
`,Q='var Module=typeof Module!="undefined"?Module:{};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof WorkerGlobalScope!="undefined";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string"&&process.type!="renderer";var ENVIRONMENT_IS_PTHREAD=ENVIRONMENT_IS_WORKER&&self.name?.startsWith("em-pthread");if(ENVIRONMENT_IS_NODE){var worker_threads=require("worker_threads");global.Worker=worker_threads.Worker;ENVIRONMENT_IS_WORKER=!worker_threads.isMainThread;ENVIRONMENT_IS_PTHREAD=ENVIRONMENT_IS_WORKER&&worker_threads["workerData"]=="em-pthread"}var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var _scriptName=typeof document!="undefined"?document.currentScript?.src:undefined;if(ENVIRONMENT_IS_NODE){_scriptName=__filename}else if(ENVIRONMENT_IS_WORKER){_scriptName=self.location.href}var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");scriptDirectory=__dirname+"/";readBinary=filename=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename);return ret};readAsync=async(filename,binary=true)=>{filename=isFileURI(filename)?new URL(filename):filename;var ret=fs.readFileSync(filename,binary?undefined:"utf8");return ret};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}if(!ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=async url=>{if(isFileURI(url)){return new Promise((resolve,reject)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){resolve(xhr.response);return}reject(xhr.status)};xhr.onerror=reject;xhr.send(null)})}var response=await fetch(url,{credentials:"same-origin"});if(response.ok){return response.arrayBuffer()}throw new Error(response.status+" : "+response.url)}}}else{}var defaultPrint=console.log.bind(console);var defaultPrintErr=console.error.bind(console);if(ENVIRONMENT_IS_NODE){defaultPrint=(...args)=>fs.writeSync(1,args.join(" ")+"\\n");defaultPrintErr=(...args)=>fs.writeSync(2,args.join(" ")+"\\n")}var out=Module["print"]||defaultPrint;var err=Module["printErr"]||defaultPrintErr;Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];var wasmBinary=Module["wasmBinary"];var wasmMemory;var wasmModule;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAP64,HEAPU64,HEAPF64;var runtimeInitialized=false;var dataURIPrefix="data:application/octet-stream;base64,";var isDataURI=filename=>filename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");function GROWABLE_HEAP_I8(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP8}function GROWABLE_HEAP_U8(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPU8}function GROWABLE_HEAP_I16(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP16}function GROWABLE_HEAP_I32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAP32}function GROWABLE_HEAP_U32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPU32}function GROWABLE_HEAP_F32(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPF32}function GROWABLE_HEAP_F64(){if(wasmMemory.buffer!=HEAP8.buffer){updateMemoryViews()}return HEAPF64}if(ENVIRONMENT_IS_PTHREAD){var wasmModuleReceived;if(ENVIRONMENT_IS_NODE){var parentPort=worker_threads["parentPort"];parentPort.on("message",msg=>onmessage({data:msg}));Object.assign(globalThis,{self:global,postMessage:msg=>parentPort.postMessage(msg)})}var initializedJS=false;function threadPrintErr(...args){v | |