@huggingface/transformers 3.3.3 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/dist/ort-wasm-simd-threaded.jsep.mjs +124 -115
- package/dist/ort-wasm-simd-threaded.jsep.wasm +0 -0
- package/dist/transformers.js +2778 -1592
- package/dist/transformers.js.map +1 -1
- package/dist/transformers.min.js +1 -1
- package/dist/transformers.min.js.map +1 -1
- package/dist/{transformers.cjs → transformers.node.cjs} +1699 -2530
- package/dist/transformers.node.cjs.map +1 -0
- package/dist/transformers.node.min.cjs +2 -0
- package/dist/transformers.node.min.cjs.map +1 -0
- package/dist/transformers.node.min.mjs +2 -0
- package/dist/transformers.node.min.mjs.map +1 -0
- package/dist/{transformers.mjs → transformers.node.mjs} +1738 -2510
- package/dist/transformers.node.mjs.map +1 -0
- package/dist/transformers.web.js +35876 -0
- package/dist/transformers.web.js.map +1 -0
- package/dist/transformers.web.min.js +2 -0
- package/dist/transformers.web.min.js.map +1 -0
- package/package.json +6 -6
- package/src/backends/onnx.js +14 -15
- package/src/configs.js +6 -1
- package/src/env.js +1 -1
- package/src/generation/streamers.js +4 -3
- package/src/models/dac/feature_extraction_dac.js +3 -0
- package/src/models/encodec/feature_extraction_encodec.js +32 -0
- package/src/models/feature_extractors.js +3 -0
- package/src/models/idefics3/image_processing_idefics3.js +1 -1
- package/src/models/image_processors.js +1 -0
- package/src/models/processors.js +2 -0
- package/src/models/smolvlm/image_processing_smolvlm.js +2 -0
- package/src/models/smolvlm/processing_smolvlm.js +2 -0
- package/src/models/snac/feature_extraction_snac.js +3 -0
- package/src/models/ultravox/processing_ultravox.js +54 -0
- package/src/models/whisper/common_whisper.js +7 -1
- package/src/models/whisper/feature_extraction_whisper.js +18 -10
- package/src/models.js +546 -78
- package/src/pipelines.js +246 -137
- package/src/tokenizers.js +42 -28
- package/src/transformers.js +1 -0
- package/src/utils/audio.js +2 -0
- package/src/utils/hub.js +140 -80
- package/src/utils/image.js +9 -1
- package/src/utils/maths.js +1 -1
- package/src/utils/tensor.js +12 -5
- package/src/utils/video.js +128 -0
- package/types/backends/onnx.d.ts +2 -2
- package/types/backends/onnx.d.ts.map +1 -1
- package/types/configs.d.ts +1 -1
- package/types/configs.d.ts.map +1 -1
- package/types/generation/streamers.d.ts.map +1 -1
- package/types/models/dac/feature_extraction_dac.d.ts +4 -0
- package/types/models/dac/feature_extraction_dac.d.ts.map +1 -0
- package/types/models/encodec/feature_extraction_encodec.d.ts +13 -0
- package/types/models/encodec/feature_extraction_encodec.d.ts.map +1 -0
- package/types/models/feature_extractors.d.ts +3 -0
- package/types/models/florence2/processing_florence2.d.ts +1 -1
- package/types/models/florence2/processing_florence2.d.ts.map +1 -1
- package/types/models/image_processors.d.ts +1 -0
- package/types/models/processors.d.ts +2 -0
- package/types/models/smolvlm/image_processing_smolvlm.d.ts +2 -0
- package/types/models/smolvlm/image_processing_smolvlm.d.ts.map +1 -0
- package/types/models/smolvlm/processing_smolvlm.d.ts +2 -0
- package/types/models/smolvlm/processing_smolvlm.d.ts.map +1 -0
- package/types/models/snac/feature_extraction_snac.d.ts +4 -0
- package/types/models/snac/feature_extraction_snac.d.ts.map +1 -0
- package/types/models/ultravox/processing_ultravox.d.ts +16 -0
- package/types/models/ultravox/processing_ultravox.d.ts.map +1 -0
- package/types/models/whisper/common_whisper.d.ts.map +1 -1
- package/types/models/whisper/feature_extraction_whisper.d.ts +3 -1
- package/types/models/whisper/feature_extraction_whisper.d.ts.map +1 -1
- package/types/models.d.ts +180 -4
- package/types/models.d.ts.map +1 -1
- package/types/pipelines.d.ts +51 -5
- package/types/pipelines.d.ts.map +1 -1
- package/types/tokenizers.d.ts.map +1 -1
- package/types/transformers.d.ts +1 -0
- package/types/tsconfig.tsbuildinfo +1 -1
- package/types/utils/audio.d.ts.map +1 -1
- package/types/utils/hub.d.ts +19 -7
- package/types/utils/hub.d.ts.map +1 -1
- package/types/utils/image.d.ts +2 -2
- package/types/utils/image.d.ts.map +1 -1
- package/types/utils/maths.d.ts +2 -2
- package/types/utils/maths.d.ts.map +1 -1
- package/types/utils/tensor.d.ts +17 -18
- package/types/utils/tensor.d.ts.map +1 -1
- package/types/utils/video.d.ts +37 -0
- package/types/utils/video.d.ts.map +1 -0
- package/dist/transformers.cjs.map +0 -1
- package/dist/transformers.min.cjs +0 -2
- package/dist/transformers.min.cjs.map +0 -1
- package/dist/transformers.min.mjs +0 -2
- package/dist/transformers.min.mjs.map +0 -1
- package/dist/transformers.mjs.map +0 -1
package/src/tokenizers.js
CHANGED
|
@@ -995,6 +995,8 @@ class Normalizer extends Callable {
|
|
|
995
995
|
return new Replace(config);
|
|
996
996
|
case 'NFC':
|
|
997
997
|
return new NFC(config);
|
|
998
|
+
case 'NFD':
|
|
999
|
+
return new NFD(config);
|
|
998
1000
|
case 'NFKC':
|
|
999
1001
|
return new NFKC(config);
|
|
1000
1002
|
case 'NFKD':
|
|
@@ -1053,50 +1055,62 @@ class Replace extends Normalizer {
|
|
|
1053
1055
|
}
|
|
1054
1056
|
|
|
1055
1057
|
/**
|
|
1056
|
-
* A normalizer that applies Unicode normalization
|
|
1058
|
+
* A normalizer that applies Unicode normalization to the input text.
|
|
1057
1059
|
* @extends Normalizer
|
|
1060
|
+
* @abstract
|
|
1058
1061
|
*/
|
|
1059
|
-
class
|
|
1062
|
+
class UnicodeNormalizer extends Normalizer {
|
|
1063
|
+
/**
|
|
1064
|
+
* @type {string} The Unicode normalization form to apply.
|
|
1065
|
+
* Should be one of: 'NFC', 'NFD', 'NFKC', or 'NFKD'.
|
|
1066
|
+
*/
|
|
1067
|
+
form = undefined;
|
|
1068
|
+
|
|
1060
1069
|
/**
|
|
1061
|
-
* Normalize the input text by applying Unicode normalization
|
|
1070
|
+
* Normalize the input text by applying Unicode normalization.
|
|
1062
1071
|
* @param {string} text The input text to be normalized.
|
|
1063
1072
|
* @returns {string} The normalized text.
|
|
1064
1073
|
*/
|
|
1065
1074
|
normalize(text) {
|
|
1066
|
-
text = text.normalize(
|
|
1075
|
+
text = text.normalize(this.form)
|
|
1067
1076
|
return text;
|
|
1068
1077
|
}
|
|
1069
1078
|
}
|
|
1070
1079
|
|
|
1071
1080
|
/**
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1081
|
+
* A normalizer that applies Unicode normalization form C (NFC) to the input text.
|
|
1082
|
+
* Canonical Decomposition, followed by Canonical Composition.
|
|
1083
|
+
* @extends UnicodeNormalizer
|
|
1074
1084
|
*/
|
|
1075
|
-
class
|
|
1076
|
-
|
|
1077
|
-
* Normalize text using NFKC normalization.
|
|
1078
|
-
* @param {string} text The text to be normalized.
|
|
1079
|
-
* @returns {string} The normalized text.
|
|
1080
|
-
*/
|
|
1081
|
-
normalize(text) {
|
|
1082
|
-
text = text.normalize('NFKC')
|
|
1083
|
-
return text;
|
|
1084
|
-
}
|
|
1085
|
+
class NFC extends UnicodeNormalizer {
|
|
1086
|
+
form = 'NFC';
|
|
1085
1087
|
}
|
|
1088
|
+
|
|
1086
1089
|
/**
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
1090
|
+
* A normalizer that applies Unicode normalization form D (NFD) to the input text.
|
|
1091
|
+
* Canonical Decomposition.
|
|
1092
|
+
* @extends UnicodeNormalizer
|
|
1089
1093
|
*/
|
|
1090
|
-
class
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1094
|
+
class NFD extends UnicodeNormalizer {
|
|
1095
|
+
form = 'NFD';
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* A normalizer that applies Unicode normalization form KC (NFKC) to the input text.
|
|
1100
|
+
* Compatibility Decomposition, followed by Canonical Composition.
|
|
1101
|
+
* @extends UnicodeNormalizer
|
|
1102
|
+
*/
|
|
1103
|
+
class NFKC extends UnicodeNormalizer {
|
|
1104
|
+
form = 'NFKC';
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* A normalizer that applies Unicode normalization form KD (NFKD) to the input text.
|
|
1109
|
+
* Compatibility Decomposition.
|
|
1110
|
+
* @extends UnicodeNormalizer
|
|
1111
|
+
*/
|
|
1112
|
+
class NFKD extends UnicodeNormalizer {
|
|
1113
|
+
form = 'NFKD';
|
|
1100
1114
|
}
|
|
1101
1115
|
|
|
1102
1116
|
/**
|
package/src/transformers.js
CHANGED
package/src/utils/audio.js
CHANGED
|
@@ -150,6 +150,7 @@ function hertz_to_mel(freq, mel_scale = "htk") {
|
|
|
150
150
|
throw new Error('mel_scale should be one of "htk", "slaney" or "kaldi".');
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
// @ts-expect-error ts(2322)
|
|
153
154
|
return typeof freq === 'number' ? fn(freq) : freq.map(x => fn(x));
|
|
154
155
|
}
|
|
155
156
|
|
|
@@ -173,6 +174,7 @@ function mel_to_hertz(mels, mel_scale = "htk") {
|
|
|
173
174
|
throw new Error('mel_scale should be one of "htk", "slaney" or "kaldi".');
|
|
174
175
|
}
|
|
175
176
|
|
|
177
|
+
// @ts-expect-error ts(2322)
|
|
176
178
|
return typeof mels === 'number' ? fn(mels) : mels.map(x => fn(x));
|
|
177
179
|
}
|
|
178
180
|
|
package/src/utils/hub.js
CHANGED
|
@@ -8,9 +8,16 @@
|
|
|
8
8
|
import fs from 'fs';
|
|
9
9
|
import path from 'path';
|
|
10
10
|
|
|
11
|
-
import { env } from '../env.js';
|
|
11
|
+
import { apis, env } from '../env.js';
|
|
12
12
|
import { dispatchCallback } from './core.js';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {boolean|number} ExternalData Whether to load the model using the external data format (used for models >= 2GB in size).
|
|
16
|
+
* If `true`, the model will be loaded using the external data format.
|
|
17
|
+
* If a number, this many chunks will be loaded using the external data format (of the form: "model.onnx_data[_{chunk_number}]").
|
|
18
|
+
*/
|
|
19
|
+
export const MAX_EXTERNAL_DATA_CHUNKS = 100;
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* @typedef {Object} PretrainedOptions Options for loading a pretrained model.
|
|
16
23
|
* @property {import('./core.js').ProgressCallback} [progress_callback=null] If specified, this function will be called during model construction, to provide the user with progress updates.
|
|
@@ -31,7 +38,7 @@ import { dispatchCallback } from './core.js';
|
|
|
31
38
|
* @property {string} [model_file_name=null] If specified, load the model with this name (excluding the .onnx suffix). Currently only valid for encoder- or decoder-only models.
|
|
32
39
|
* @property {import("./devices.js").DeviceType|Record<string, import("./devices.js").DeviceType>} [device=null] The device to run the model on. If not specified, the device will be chosen from the environment settings.
|
|
33
40
|
* @property {import("./dtypes.js").DataType|Record<string, import("./dtypes.js").DataType>} [dtype=null] The data type to use for the model. If not specified, the data type will be chosen from the environment settings.
|
|
34
|
-
* @property {
|
|
41
|
+
* @property {ExternalData|Record<string, ExternalData>} [use_external_data_format=false] Whether to load the model using the external data format (used for models >= 2GB in size).
|
|
35
42
|
* @property {import('onnxruntime-common').InferenceSession.SessionOptions} [session_options] (Optional) User-specified session options passed to the runtime. If not provided, suitable defaults will be chosen.
|
|
36
43
|
*/
|
|
37
44
|
|
|
@@ -57,7 +64,7 @@ class FileResponse {
|
|
|
57
64
|
|
|
58
65
|
/**
|
|
59
66
|
* Creates a new `FileResponse` object.
|
|
60
|
-
* @param {string
|
|
67
|
+
* @param {string} filePath
|
|
61
68
|
*/
|
|
62
69
|
constructor(filePath) {
|
|
63
70
|
this.filePath = filePath;
|
|
@@ -73,13 +80,15 @@ class FileResponse {
|
|
|
73
80
|
|
|
74
81
|
this.updateContentType();
|
|
75
82
|
|
|
76
|
-
|
|
83
|
+
const stream = fs.createReadStream(filePath);
|
|
77
84
|
this.body = new ReadableStream({
|
|
78
85
|
start(controller) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
stream.on('data', (chunk) => controller.enqueue(chunk));
|
|
87
|
+
stream.on('end', () => controller.close());
|
|
88
|
+
stream.on('error', (err) => controller.error(err));
|
|
89
|
+
},
|
|
90
|
+
cancel() {
|
|
91
|
+
stream.destroy();
|
|
83
92
|
}
|
|
84
93
|
});
|
|
85
94
|
} else {
|
|
@@ -190,7 +199,7 @@ function isValidUrl(string, protocols = null, validHosts = null) {
|
|
|
190
199
|
export async function getFile(urlOrPath) {
|
|
191
200
|
|
|
192
201
|
if (env.useFS && !isValidUrl(urlOrPath, ['http:', 'https:', 'blob:'])) {
|
|
193
|
-
return new FileResponse(urlOrPath);
|
|
202
|
+
return new FileResponse(urlOrPath.toString());
|
|
194
203
|
|
|
195
204
|
} else if (typeof process !== 'undefined' && process?.release?.name === 'node') {
|
|
196
205
|
const IS_CI = !!process.env?.TESTING_REMOTELY;
|
|
@@ -281,20 +290,52 @@ class FileCache {
|
|
|
281
290
|
/**
|
|
282
291
|
* Adds the given response to the cache.
|
|
283
292
|
* @param {string} request
|
|
284
|
-
* @param {Response
|
|
293
|
+
* @param {Response} response
|
|
294
|
+
* @param {(data: {progress: number, loaded: number, total: number}) => void} [progress_callback] Optional.
|
|
295
|
+
* The function to call with progress updates
|
|
285
296
|
* @returns {Promise<void>}
|
|
286
297
|
*/
|
|
287
|
-
async put(request, response) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
let outputPath = path.join(this.path, request);
|
|
298
|
+
async put(request, response, progress_callback = undefined) {
|
|
299
|
+
let filePath = path.join(this.path, request);
|
|
291
300
|
|
|
292
301
|
try {
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
const contentLength = response.headers.get('Content-Length');
|
|
303
|
+
const total = parseInt(contentLength ?? '0');
|
|
304
|
+
let loaded = 0;
|
|
305
|
+
|
|
306
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
307
|
+
const fileStream = fs.createWriteStream(filePath);
|
|
308
|
+
const reader = response.body.getReader();
|
|
309
|
+
|
|
310
|
+
while (true) {
|
|
311
|
+
const { done, value } = await reader.read();
|
|
312
|
+
if (done) {
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
await new Promise((resolve, reject) => {
|
|
317
|
+
fileStream.write(value, (err) => {
|
|
318
|
+
if (err) {
|
|
319
|
+
reject(err);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
resolve();
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
loaded += value.length;
|
|
327
|
+
const progress = total ? (loaded / total) * 100 : 0;
|
|
328
|
+
|
|
329
|
+
progress_callback?.({ progress, loaded, total });
|
|
330
|
+
}
|
|
295
331
|
|
|
296
|
-
|
|
297
|
-
|
|
332
|
+
fileStream.close();
|
|
333
|
+
} catch (error) {
|
|
334
|
+
// Clean up the file if an error occurred during download
|
|
335
|
+
try {
|
|
336
|
+
await fs.promises.unlink(filePath);
|
|
337
|
+
} catch { }
|
|
338
|
+
throw error;
|
|
298
339
|
}
|
|
299
340
|
}
|
|
300
341
|
|
|
@@ -325,21 +366,21 @@ async function tryCache(cache, ...names) {
|
|
|
325
366
|
}
|
|
326
367
|
|
|
327
368
|
/**
|
|
328
|
-
*
|
|
329
369
|
* Retrieves a file from either a remote URL using the Fetch API or from the local file system using the FileSystem API.
|
|
330
370
|
* If the filesystem is available and `env.useCache = true`, the file will be downloaded and cached.
|
|
331
|
-
*
|
|
371
|
+
*
|
|
332
372
|
* @param {string} path_or_repo_id This can be either:
|
|
333
373
|
* - a string, the *model id* of a model repo on huggingface.co.
|
|
334
374
|
* - a path to a *directory* potentially containing the file.
|
|
335
375
|
* @param {string} filename The name of the file to locate in `path_or_repo`.
|
|
336
376
|
* @param {boolean} [fatal=true] Whether to throw an error if the file is not found.
|
|
337
377
|
* @param {PretrainedOptions} [options] An object containing optional parameters.
|
|
338
|
-
*
|
|
378
|
+
* @param {boolean} [return_path=false] Whether to return the path of the file instead of the file content.
|
|
379
|
+
*
|
|
339
380
|
* @throws Will throw an error if the file is not found and `fatal` is true.
|
|
340
|
-
* @returns {Promise<Uint8Array>} A Promise that resolves with the file content as a
|
|
381
|
+
* @returns {Promise<string|Uint8Array>} A Promise that resolves with the file content as a Uint8Array if `return_path` is false, or the file path as a string if `return_path` is true.
|
|
341
382
|
*/
|
|
342
|
-
export async function getModelFile(path_or_repo_id, filename, fatal = true, options = {}) {
|
|
383
|
+
export async function getModelFile(path_or_repo_id, filename, fatal = true, options = {}, return_path = false) {
|
|
343
384
|
|
|
344
385
|
if (!env.allowLocalModels) {
|
|
345
386
|
// User has disabled local models, so we just make sure other settings are correct.
|
|
@@ -403,8 +444,9 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
403
444
|
const revision = options.revision ?? 'main';
|
|
404
445
|
|
|
405
446
|
let requestURL = pathJoin(path_or_repo_id, filename);
|
|
406
|
-
let
|
|
447
|
+
let cachePath = pathJoin(env.localModelPath, requestURL);
|
|
407
448
|
|
|
449
|
+
let localPath = requestURL;
|
|
408
450
|
let remoteURL = pathJoin(
|
|
409
451
|
env.remoteHost,
|
|
410
452
|
env.remotePathTemplate
|
|
@@ -433,7 +475,7 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
433
475
|
// 1. We first try to get from cache using the local path. In some environments (like deno),
|
|
434
476
|
// non-URL cache keys are not allowed. In these cases, `response` will be undefined.
|
|
435
477
|
// 2. If no response is found, we try to get from cache using the remote URL or file system cache.
|
|
436
|
-
response = await tryCache(cache,
|
|
478
|
+
response = await tryCache(cache, cachePath, proposedCacheKey);
|
|
437
479
|
}
|
|
438
480
|
|
|
439
481
|
const cacheHit = response !== undefined;
|
|
@@ -455,9 +497,9 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
455
497
|
console.warn(`Unable to load from local path "${localPath}": "${e}"`);
|
|
456
498
|
}
|
|
457
499
|
} else if (options.local_files_only) {
|
|
458
|
-
throw new Error(`\`local_files_only=true\`, but attempted to load a remote file from: ${
|
|
500
|
+
throw new Error(`\`local_files_only=true\`, but attempted to load a remote file from: ${localPath}.`);
|
|
459
501
|
} else if (!env.allowRemoteModels) {
|
|
460
|
-
throw new Error(`\`env.allowRemoteModels=false\`, but attempted to load a remote file from: ${
|
|
502
|
+
throw new Error(`\`env.allowRemoteModels=false\`, but attempted to load a remote file from: ${localPath}.`);
|
|
461
503
|
}
|
|
462
504
|
}
|
|
463
505
|
|
|
@@ -504,41 +546,45 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
504
546
|
file: filename
|
|
505
547
|
})
|
|
506
548
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
name: path_or_repo_id,
|
|
528
|
-
file: filename,
|
|
529
|
-
progress: 100,
|
|
530
|
-
loaded: buffer.length,
|
|
531
|
-
total: buffer.length,
|
|
532
|
-
})
|
|
533
|
-
} else {
|
|
534
|
-
buffer = await readResponse(response, data => {
|
|
549
|
+
let result;
|
|
550
|
+
if (!(apis.IS_NODE_ENV && return_path)) {
|
|
551
|
+
/** @type {Uint8Array} */
|
|
552
|
+
let buffer;
|
|
553
|
+
|
|
554
|
+
if (!options.progress_callback) {
|
|
555
|
+
// If no progress callback is specified, we can use the `.arrayBuffer()`
|
|
556
|
+
// method to read the response.
|
|
557
|
+
buffer = new Uint8Array(await response.arrayBuffer());
|
|
558
|
+
|
|
559
|
+
} else if (
|
|
560
|
+
cacheHit // The item is being read from the cache
|
|
561
|
+
&&
|
|
562
|
+
typeof navigator !== 'undefined' && /firefox/i.test(navigator.userAgent) // We are in Firefox
|
|
563
|
+
) {
|
|
564
|
+
// Due to bug in Firefox, we cannot display progress when loading from cache.
|
|
565
|
+
// Fortunately, since this should be instantaneous, this should not impact users too much.
|
|
566
|
+
buffer = new Uint8Array(await response.arrayBuffer());
|
|
567
|
+
|
|
568
|
+
// For completeness, we still fire the final progress callback
|
|
535
569
|
dispatchCallback(options.progress_callback, {
|
|
536
570
|
status: 'progress',
|
|
537
571
|
name: path_or_repo_id,
|
|
538
572
|
file: filename,
|
|
539
|
-
|
|
573
|
+
progress: 100,
|
|
574
|
+
loaded: buffer.length,
|
|
575
|
+
total: buffer.length,
|
|
540
576
|
})
|
|
541
|
-
}
|
|
577
|
+
} else {
|
|
578
|
+
buffer = await readResponse(response, data => {
|
|
579
|
+
dispatchCallback(options.progress_callback, {
|
|
580
|
+
status: 'progress',
|
|
581
|
+
name: path_or_repo_id,
|
|
582
|
+
file: filename,
|
|
583
|
+
...data,
|
|
584
|
+
})
|
|
585
|
+
})
|
|
586
|
+
}
|
|
587
|
+
result = buffer;
|
|
542
588
|
}
|
|
543
589
|
|
|
544
590
|
if (
|
|
@@ -549,25 +595,43 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
549
595
|
// Check again whether request is in cache. If not, we add the response to the cache
|
|
550
596
|
(await cache.match(cacheKey) === undefined)
|
|
551
597
|
) {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
598
|
+
if (!result) {
|
|
599
|
+
// We haven't yet read the response body, so we need to do so now.
|
|
600
|
+
await cache.put(cacheKey, /** @type {Response} */(response), options.progress_callback);
|
|
601
|
+
} else {
|
|
602
|
+
// NOTE: We use `new Response(buffer, ...)` instead of `response.clone()` to handle LFS files
|
|
603
|
+
await cache.put(cacheKey, new Response(result, {
|
|
604
|
+
headers: response.headers
|
|
605
|
+
}))
|
|
606
|
+
.catch(err => {
|
|
607
|
+
// Do not crash if unable to add to cache (e.g., QuotaExceededError).
|
|
608
|
+
// Rather, log a warning and proceed with execution.
|
|
609
|
+
console.warn(`Unable to add response to browser cache: ${err}.`);
|
|
610
|
+
});
|
|
611
|
+
}
|
|
562
612
|
}
|
|
563
|
-
|
|
564
613
|
dispatchCallback(options.progress_callback, {
|
|
565
614
|
status: 'done',
|
|
566
615
|
name: path_or_repo_id,
|
|
567
616
|
file: filename
|
|
568
617
|
});
|
|
569
618
|
|
|
570
|
-
|
|
619
|
+
if (result) {
|
|
620
|
+
if (return_path) {
|
|
621
|
+
throw new Error("Cannot return path in a browser environment.")
|
|
622
|
+
}
|
|
623
|
+
return result;
|
|
624
|
+
}
|
|
625
|
+
if (response instanceof FileResponse) {
|
|
626
|
+
return response.filePath;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const path = await cache.match(cacheKey);
|
|
630
|
+
if (path instanceof FileResponse) {
|
|
631
|
+
return path.filePath;
|
|
632
|
+
}
|
|
633
|
+
throw new Error("Unable to return path for response.");
|
|
634
|
+
|
|
571
635
|
}
|
|
572
636
|
|
|
573
637
|
/**
|
|
@@ -581,14 +645,14 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti
|
|
|
581
645
|
* @throws Will throw an error if the file is not found and `fatal` is true.
|
|
582
646
|
*/
|
|
583
647
|
export async function getModelJSON(modelPath, fileName, fatal = true, options = {}) {
|
|
584
|
-
|
|
648
|
+
const buffer = await getModelFile(modelPath, fileName, fatal, options, false);
|
|
585
649
|
if (buffer === null) {
|
|
586
650
|
// Return empty object
|
|
587
651
|
return {}
|
|
588
652
|
}
|
|
589
653
|
|
|
590
|
-
|
|
591
|
-
|
|
654
|
+
const decoder = new TextDecoder('utf-8');
|
|
655
|
+
const jsonData = decoder.decode(/** @type {Uint8Array} */(buffer));
|
|
592
656
|
|
|
593
657
|
return JSON.parse(jsonData);
|
|
594
658
|
}
|
|
@@ -614,30 +678,26 @@ async function readResponse(response, progress_callback) {
|
|
|
614
678
|
const { done, value } = await reader.read();
|
|
615
679
|
if (done) return;
|
|
616
680
|
|
|
617
|
-
|
|
681
|
+
const newLoaded = loaded + value.length;
|
|
618
682
|
if (newLoaded > total) {
|
|
619
683
|
total = newLoaded;
|
|
620
684
|
|
|
621
685
|
// Adding the new data will overflow buffer.
|
|
622
686
|
// In this case, we extend the buffer
|
|
623
|
-
|
|
687
|
+
const newBuffer = new Uint8Array(total);
|
|
624
688
|
|
|
625
689
|
// copy contents
|
|
626
690
|
newBuffer.set(buffer);
|
|
627
691
|
|
|
628
692
|
buffer = newBuffer;
|
|
629
693
|
}
|
|
630
|
-
buffer.set(value, loaded)
|
|
694
|
+
buffer.set(value, loaded);
|
|
631
695
|
loaded = newLoaded;
|
|
632
696
|
|
|
633
697
|
const progress = (loaded / total) * 100;
|
|
634
698
|
|
|
635
699
|
// Call your function here
|
|
636
|
-
progress_callback({
|
|
637
|
-
progress: progress,
|
|
638
|
-
loaded: loaded,
|
|
639
|
-
total: total,
|
|
640
|
-
})
|
|
700
|
+
progress_callback({ progress, loaded, total });
|
|
641
701
|
|
|
642
702
|
return read();
|
|
643
703
|
}
|
package/src/utils/image.js
CHANGED
|
@@ -100,7 +100,7 @@ export class RawImage {
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
102
102
|
* Helper method for reading an image from a variety of input types.
|
|
103
|
-
* @param {RawImage|string|URL} input
|
|
103
|
+
* @param {RawImage|string|URL|Blob|HTMLCanvasElement|OffscreenCanvas} input
|
|
104
104
|
* @returns The image object.
|
|
105
105
|
*
|
|
106
106
|
* **Example:** Read image from a URL.
|
|
@@ -119,6 +119,14 @@ export class RawImage {
|
|
|
119
119
|
return input;
|
|
120
120
|
} else if (typeof input === 'string' || input instanceof URL) {
|
|
121
121
|
return await this.fromURL(input);
|
|
122
|
+
} else if (input instanceof Blob) {
|
|
123
|
+
return await this.fromBlob(input);
|
|
124
|
+
} else if (
|
|
125
|
+
(typeof HTMLCanvasElement !== "undefined" && input instanceof HTMLCanvasElement)
|
|
126
|
+
||
|
|
127
|
+
(typeof OffscreenCanvas !== "undefined" && input instanceof OffscreenCanvas)
|
|
128
|
+
) {
|
|
129
|
+
return this.fromCanvas(input);
|
|
122
130
|
} else {
|
|
123
131
|
throw new Error(`Unsupported input type: ${typeof input}`);
|
|
124
132
|
}
|
package/src/utils/maths.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray
|
|
12
|
+
* @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float16Array | Float32Array | Float64Array} TypedArray
|
|
13
13
|
* @typedef {BigInt64Array | BigUint64Array} BigTypedArray
|
|
14
14
|
* @typedef {TypedArray | BigTypedArray} AnyTypedArray
|
|
15
15
|
*/
|
package/src/utils/tensor.js
CHANGED
|
@@ -20,9 +20,11 @@ import {
|
|
|
20
20
|
|
|
21
21
|
import { TensorOpRegistry } from '../ops/registry.js';
|
|
22
22
|
|
|
23
|
-
const DataTypeMap = Object.freeze({
|
|
23
|
+
export const DataTypeMap = Object.freeze({
|
|
24
24
|
float32: Float32Array,
|
|
25
|
-
|
|
25
|
+
// @ts-ignore ts(2552) Limited availability of Float16Array across browsers:
|
|
26
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float16Array
|
|
27
|
+
float16: typeof Float16Array !== "undefined" ? Float16Array: Uint16Array,
|
|
26
28
|
float64: Float64Array,
|
|
27
29
|
string: Array, // string[]
|
|
28
30
|
int8: Int8Array,
|
|
@@ -89,8 +91,9 @@ export class Tensor {
|
|
|
89
91
|
// Create new tensor
|
|
90
92
|
this.ort_tensor = new ONNXTensor(
|
|
91
93
|
/** @type {DataType} */(args[0]),
|
|
94
|
+
// @ts-expect-error ts(2769) Type 'number' is not assignable to type 'bigint'.
|
|
92
95
|
/** @type {Exclude<import('./maths.js').AnyTypedArray, Uint8ClampedArray>} */(args[1]),
|
|
93
|
-
args[2]
|
|
96
|
+
args[2],
|
|
94
97
|
);
|
|
95
98
|
}
|
|
96
99
|
|
|
@@ -1179,8 +1182,12 @@ function calc_unsqueeze_dims(dims, dim) {
|
|
|
1179
1182
|
* @private
|
|
1180
1183
|
*/
|
|
1181
1184
|
function safeIndex(index, size, dimension = null, boundsCheck = true) {
|
|
1182
|
-
if (
|
|
1183
|
-
|
|
1185
|
+
if (index < -size || index >= size) {
|
|
1186
|
+
if (boundsCheck) {
|
|
1187
|
+
throw new Error(`IndexError: index ${index} is out of bounds for dimension${dimension === null ? '' : ' ' + dimension} with size ${size}`);
|
|
1188
|
+
} else {
|
|
1189
|
+
return index < -size ? 0 : size;
|
|
1190
|
+
}
|
|
1184
1191
|
}
|
|
1185
1192
|
|
|
1186
1193
|
if (index < 0) {
|