Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support React Native #118

Open
wants to merge 144 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
1aefcb6
Support for ReactNative
hans00 May 17, 2023
38acc1e
Correct module import
hans00 May 17, 2023
0d7faf0
Update package-lock
hans00 May 17, 2023
c1da2c8
fix errors
hans00 May 17, 2023
bb550f1
fix error
hans00 May 17, 2023
35d8f18
Merge branch 'xenova:main' into main
hans00 May 17, 2023
83cd1e6
Prevent fallback WASM on RN
hans00 May 17, 2023
f64e61b
Let native side load binary file, instead load as buffer
hans00 May 17, 2023
85d75ef
Fix 0 size tensor
hans00 May 17, 2023
392dc67
Correct version
hans00 May 17, 2023
c9cada9
Constantly fetch arraybuffer
hans00 May 17, 2023
20f128f
Replace `Uint8Array` as `Buffer` on RN
hans00 May 17, 2023
891a0a4
Revert version
hans00 May 17, 2023
fd302ae
Merge native codes
hans00 May 19, 2023
37e89cf
Fix test
hans00 May 19, 2023
9ee7504
Disable `image-encode` and `image-decode` for web
hans00 May 19, 2023
91ecc47
Sync code
hans00 May 19, 2023
17bc3e8
Use `RNFS.downloadFile` to avoid OOM on large model file.
hans00 May 19, 2023
58c2468
Correct download progress order
hans00 May 19, 2023
52be4db
Fix bug
hans00 May 19, 2023
e0683b3
Merge branch 'xenova:main' into main
hans00 May 19, 2023
362a0c7
Fix error
hans00 May 19, 2023
c633a2d
Use `interpolate_data` instead `resize-image-data`
hans00 May 19, 2023
798edec
Correct params
hans00 May 19, 2023
8c66b31
Support `react-native-gcanvas` to improve image parse performance
hans00 May 19, 2023
874340c
Correct algorithm impl
hans00 May 20, 2023
e9c2872
Use `interpolate_data` to resize
hans00 May 20, 2023
7fad900
Reuse code
hans00 May 20, 2023
327fb59
`ImageData` not need wrap with `Uint8ClampedArray`
hans00 May 20, 2023
ac85425
Add switch to enable use GCanvas
hans00 May 20, 2023
7b9232f
Support gCanvas on `resize`, `crop` and `pad`
hans00 May 21, 2023
47711c8
Force use latest `jpeg-js`
hans00 May 21, 2023
c2f01bd
Use `XRegExp` to support unicode on RN
hans00 May 21, 2023
185c58f
Revert "Use `XRegExp` to support unicode on RN"
hans00 May 21, 2023
e86687d
Add missing var
hans00 May 21, 2023
b7521c5
Set `useGCanvas` default true, instead env check
hans00 May 21, 2023
1730bea
Log full tensor on browser
hans00 May 21, 2023
ff64922
Merge branch 'xenova:main' into main
hans00 May 22, 2023
0e54440
Update package-lock.json
hans00 May 22, 2023
3f32b71
Use dynamic import to select backend
hans00 May 25, 2023
fd0fa22
Add `onnxruntime-react-native` in optional
hans00 May 25, 2023
3edb592
Set browser ignore
hans00 May 25, 2023
4f6b788
Fix runtime setup
hans00 May 25, 2023
0ac4b4e
Default export `onnxruntime-common`
hans00 May 25, 2023
0a260c5
Add missing var
hans00 May 25, 2023
7b2667b
Fix `browser` field for `react-native`
hans00 May 25, 2023
28e8f8d
Fix import
hans00 May 25, 2023
8069844
Fix build
hans00 May 25, 2023
a5682dd
Allow fallback `web` on node-like environment
hans00 May 25, 2023
77ac38e
Merge branch 'main' into merge
hans00 May 30, 2023
57e4bc8
Merge branch 'main' into merge
hans00 Jun 2, 2023
eee34a4
Merge branch 'xenova:main' into merge
hans00 Jun 30, 2023
e09f2d9
Correct variable
hans00 Jul 4, 2023
9e7d629
Fix error on load model
hans00 Jul 4, 2023
311cb9c
Merge branch 'main' into merge
hans00 Jul 12, 2023
6f85b28
Merge branch 'main' into merge
hans00 Jul 29, 2023
f27121d
Merge branch 'main' into merge
hans00 Aug 6, 2023
973f33a
Correct package.json
hans00 Aug 7, 2023
d70abf9
Export `isReady` promise
hans00 Aug 7, 2023
44f0668
Merge branch 'main' into merge
hans00 Aug 8, 2023
dff8dbb
Use `react-native` field to replace module
hans00 Aug 15, 2023
7d49523
Merge branch 'xenova:main' into merge
hans00 Aug 18, 2023
4b63d92
Add missing optionalDeps
hans00 Aug 22, 2023
2050020
Merge branch 'main' into merge
hans00 Aug 23, 2023
d6d42dc
Fix config file never cache
hans00 Aug 23, 2023
8aa2993
Merge branch 'xenova:main' into merge
hans00 Sep 8, 2023
f98160f
Fix missing var
hans00 Sep 8, 2023
214ba14
Avoid use preserve word
hans00 Sep 11, 2023
7fe660b
Support `OffscreenCanvas` polyfill without `document`
hans00 Oct 3, 2023
b95a836
Merge branch 'main' into merge
hans00 Oct 3, 2023
d14ec8e
Fix `type` is missing
hans00 Oct 12, 2023
d49b0d0
Merge branch 'xenova:main' into merge
hans00 Oct 24, 2023
2fdf3e6
Opt-out wasm for RN and wait runtime loaded
hans00 Oct 30, 2023
ee89374
Merge branch 'main' into merge
hans00 Nov 10, 2023
95526e0
Merge branch 'xenova:main' into merge
hans00 Nov 16, 2023
2d54b61
Merge branch 'main' into merge
hans00 Dec 13, 2023
73b9131
Merge branch 'main' into merge
hans00 Dec 24, 2023
24726fa
Update `package-lock.json`
hans00 Dec 24, 2023
880348a
Fix error
hans00 Dec 24, 2023
1210102
Fix fetch binary for TTS
hans00 Dec 24, 2023
27e8434
Fix error when file cached
hans00 Dec 24, 2023
b16ad4c
Merge branch 'xenova:main' into merge
hans00 Dec 31, 2023
c5bbba5
Merge branch 'main' into merge
hans00 Jan 3, 2024
ad60a9b
Merge branch 'main' into merge
hans00 Jan 14, 2024
b42d06c
break trying load if backend error
hans00 Jan 17, 2024
2e15702
Fix web support
hans00 Jan 17, 2024
a94b45a
Bump onnxruntime
hans00 Jan 17, 2024
4a8a5bb
Remove `isReady` check
hans00 Jan 17, 2024
af1d6f6
Only continue on `Unsupported model type`
hans00 Jan 17, 2024
8a234c5
Continue on file 404 error
hans00 Jan 17, 2024
566ec32
Fix error on node
hans00 Jan 17, 2024
6e3affa
Exclude `wasm` for RN
hans00 Jan 18, 2024
79979e8
Merge branch 'xenova:main' into merge
hans00 Feb 1, 2024
c7aa59f
Merge branch 'main' into merge
hans00 Feb 13, 2024
3592613
Update `package-lock.json`
hans00 Feb 13, 2024
685b718
Support decode wav
hans00 Feb 17, 2024
2a35254
add `node-wav`
hans00 Feb 23, 2024
718c3d7
Merge branch 'main' into merge
hans00 Feb 23, 2024
755f5ba
Fix `package.json`
hans00 Feb 24, 2024
95faa44
Bump onnxruntime
hans00 Feb 24, 2024
c0dda59
Update `package-lock.json`
hans00 Feb 24, 2024
7fb93d9
Fix typo
hans00 Feb 24, 2024
d4d6ebf
Support Tensor of `onnxruntime@1.17.0`
hans00 Feb 24, 2024
5a0d504
Correct algorithm implement
hans00 Feb 24, 2024
8cd25a4
Correct resample factor behavior
hans00 Feb 24, 2024
b597fa4
Rename `useGCanvas` to `useRNCanvas`
hans00 Feb 24, 2024
f7222ec
Better naming, change `useRNCanvas` to `rnUseCanvas`
hans00 Feb 24, 2024
5a23e2f
Fix `Tensor` index getter
hans00 Feb 25, 2024
a089ef0
Fix not work with spread transform
hans00 Feb 25, 2024
306b208
Add dispose to release memory
hans00 Feb 25, 2024
431983b
Support `crop` for ReactNative
hans00 Feb 25, 2024
060a2e5
Change to `image-codecs`
hans00 Feb 25, 2024
7ad4ef2
Setup `image-codecs`
hans00 Feb 25, 2024
b4a4bce
Correct URI format
hans00 Feb 25, 2024
9b7faf9
Fix bug
hans00 Feb 25, 2024
d697e77
Fix error process
hans00 Feb 28, 2024
173cc09
Correct error process
hans00 Feb 28, 2024
0d31927
Merge branch 'main' into merge
hans00 Mar 6, 2024
eb56058
Update package-lock.json
hans00 Mar 6, 2024
1a2bc57
Merge branch 'main' into merge
hans00 Mar 8, 2024
3dd8855
Disable WASM configure for React Native
hans00 Mar 18, 2024
b41e23c
Move `readFile` into `FileResponse`
hans00 Mar 26, 2024
840fa5c
Support load model from local path for RN & Node.js
hans00 Mar 26, 2024
9e15f15
Merge branch 'main' into merge
hans00 Mar 26, 2024
d81b459
Fix missing function
hans00 Mar 27, 2024
333c547
Update package-lock
hans00 Mar 27, 2024
0a29022
Fix missing var
hans00 Mar 27, 2024
dc05218
Use `fetch` for non-RN env
hans00 Mar 27, 2024
243f7fd
Cleanup invalid doc
hans00 Mar 27, 2024
bad3882
Add `session_options`
hans00 Apr 3, 2024
4098dd0
Fix `session_options` not work
hans00 Apr 3, 2024
800a476
Use same option for path load
hans00 Apr 3, 2024
c7fdd36
Fix `session_options`
hans00 Apr 3, 2024
c9bed9c
Correct logic
hans00 Apr 3, 2024
f835060
Fix model load
hans00 Apr 3, 2024
fbd7136
Return file path if not RN
hans00 Apr 4, 2024
6da74ff
Prevent readFile when get model path
hans00 Apr 8, 2024
3a3fa29
Merge branch 'main' into merge
hans00 Apr 20, 2024
22cbfe9
Update package-lock
hans00 Apr 20, 2024
c986a8c
Merge branch 'main' into merge
hans00 May 13, 2024
8df376b
Fix syntax
hans00 May 13, 2024
9f30f1b
Merge branch 'main' into merge
hans00 Jun 10, 2024
9109355
Fix model file download
hans00 Jun 18, 2024
918950e
Merge branch 'main' into merge
hans00 Jul 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8,074 changes: 3,262 additions & 4,812 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 21 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@
},
"homepage": "https://github.com/xenova/transformers.js#readme",
"dependencies": {
"onnxruntime-web": "1.14.0",
"sharp": "^0.32.0",
"@huggingface/jinja": "^0.2.2"
"@huggingface/jinja": "^0.2.2",
"image-codecs": "^0.1.0",
"node-wav": "^0.0.2",
"onnxruntime-web": "^1.17.0",
"sharp": "^0.32.0"
},
"optionalDependencies": {
"onnxruntime-node": "1.14.0"
"browserify-zlib": "^0.2.0",
"onnxruntime-node": "^1.17.0",
"onnxruntime-react-native": "^1.17.0",
"path-browserify": "^1.0.1",
"react-native-fs": "^2.20.0"
},
"devDependencies": {
"@types/jest": "^29.5.1",
Expand All @@ -59,6 +65,7 @@
"webpack-dev-server": "^4.13.3"
},
"overrides": {
"jpeg-js": "^0.4.4",
"semver": "^7.5.4",
"protobufjs": "^7.2.6"
},
Expand All @@ -69,8 +76,18 @@
"README.md",
"LICENSE"
],
"react-native": {
"fs": "react-native-fs",
"onnxruntime-web": false,
"onnxruntime-node": "onnxruntime-react-native",
"image-codecs": "image-codecs",
"path": "path-browserify",
"stream/web": false,
"zlib": "browserify-zlib"
},
"browser": {
"fs": false,
"image-codecs": false,
"path": false,
"url": false,
"sharp": false,
Expand Down
12 changes: 10 additions & 2 deletions src/backends/onnx.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,15 @@ export const executionProviders = [
'wasm'
];

if (typeof process !== 'undefined' && process?.release?.name === 'node') {
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
// Running in a RN or node-like environment.
ONNX = ONNX_NODE.default ?? ONNX_NODE;

// Add `cpu` execution provider, and remove `wasm`.
executionProviders.unshift('cpu');
executionProviders.splice(executionProviders.indexOf('wasm'), 1);

} else if (typeof process !== 'undefined' && process?.release?.name === 'node') {
// Running in a node-like environment.
ONNX = ONNX_NODE.default ?? ONNX_NODE;

Expand All @@ -47,4 +55,4 @@ if (typeof process !== 'undefined' && process?.release?.name === 'node') {
if (isIOS) {
ONNX.env.wasm.simd = false;
}
}
}
28 changes: 19 additions & 9 deletions src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,41 +25,47 @@
import fs from 'fs';
import path from 'path';
import url from 'url';
import { Buffer } from 'buffer';

import { ONNX } from './backends/onnx.js';
const { env: onnx_env } = ONNX;

const VERSION = '2.17.2';

// Check if various APIs are available (depends on environment)
const IS_REACT_NATIVE = typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
const WEB_CACHE_AVAILABLE = typeof self !== 'undefined' && 'caches' in self;
const FS_AVAILABLE = !isEmpty(fs); // check if file system is available
const FS_AVAILABLE = !isEmpty(fs) || IS_REACT_NATIVE; // check if file system is available
const PATH_AVAILABLE = !isEmpty(path); // check if path is available

const RUNNING_LOCALLY = FS_AVAILABLE && PATH_AVAILABLE;

const __dirname = RUNNING_LOCALLY
? path.dirname(path.dirname(url.fileURLToPath(import.meta.url)))
: './';

let localPath = './';
if (IS_REACT_NATIVE) {
localPath = fs.DocumentDirectoryPath;
} else if (RUNNING_LOCALLY) {
localPath = path.dirname(path.dirname(url.fileURLToPath(import.meta.url)));
}

// Only used for environments with access to file system
const DEFAULT_CACHE_DIR = RUNNING_LOCALLY
? path.join(__dirname, '/.cache/')
? path.join(localPath, '/.cache/')
: null;

// Set local model path, based on available APIs
const DEFAULT_LOCAL_MODEL_PATH = '/models/';
const localModelPath = RUNNING_LOCALLY
? path.join(__dirname, DEFAULT_LOCAL_MODEL_PATH)
? path.join(localPath, DEFAULT_LOCAL_MODEL_PATH)
: DEFAULT_LOCAL_MODEL_PATH;

if (onnx_env?.wasm) {
if (!IS_REACT_NATIVE && onnx_env?.wasm) {
// Set path to wasm files. This is needed when running in a web worker.
// https://onnxruntime.ai/docs/api/js/interfaces/Env.WebAssemblyFlags.html#wasmPaths
// We use remote wasm files by default to make it easier for newer users.
// In practice, users should probably self-host the necessary .wasm files.
onnx_env.wasm.wasmPaths = RUNNING_LOCALLY
? path.join(__dirname, '/dist/')
? path.join(localPath, '/dist/')
: `https://cdn.jsdelivr.net/npm/@xenova/transformers@${VERSION}/dist/`;
}

Expand Down Expand Up @@ -92,9 +98,11 @@ export const env = {

// TensorFlow.js
tfjs: {},

Uint8Array: IS_REACT_NATIVE ? Buffer : Uint8Array,
},

__dirname,
__dirname: localPath,
version: VERSION,

/////////////////// Model settings ///////////////////
Expand All @@ -106,6 +114,8 @@ export const env = {
localModelPath: localModelPath,
useFS: FS_AVAILABLE,

rnUseCanvas: true,

/////////////////// Cache settings ///////////////////
useBrowserCache: WEB_CACHE_AVAILABLE,

Expand Down
57 changes: 33 additions & 24 deletions src/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {

import {
getModelFile,
getModelPath,
getModelJSON,
} from './utils/hub.js';

Expand Down Expand Up @@ -81,12 +82,16 @@ import {
Tensor,
} from './utils/tensor.js';

import { env } from './env.js';

import { executionProviders, ONNX } from './backends/onnx.js';
import { medianFilter } from './transformers.js';
const { InferenceSession, Tensor: ONNXTensor, env } = ONNX;
const { InferenceSession, Tensor: ONNXTensor, env: onnx_env } = ONNX;

/** @typedef {import('onnxruntime-web').InferenceSession} InferenceSession */

const IS_BROWSER = typeof navigator !== 'undefined' && navigator.product !== 'ReactNative';

//////////////////////////////////////////////////
// Model types: used internally
const MODEL_TYPES = {
Expand Down Expand Up @@ -119,27 +124,20 @@ const MODEL_CLASS_TO_NAME_MAPPING = new Map();
*/
async function constructSession(pretrained_model_name_or_path, fileName, options) {
// TODO add option for user to force specify their desired execution provider
let modelFileName = `onnx/${fileName}${options.quantized ? '_quantized' : ''}.onnx`;
let buffer = await getModelFile(pretrained_model_name_or_path, modelFileName, true, options);

try {
return await InferenceSession.create(buffer, {
executionProviders,
});
} catch (err) {
// If the execution provided was only wasm, throw the error
if (executionProviders.length === 1 && executionProviders[0] === 'wasm') {
throw err;
}
const sessionOptions = { executionProviders, ...options.session_options };
const modelFileName = `onnx/${fileName}${options.quantized ? '_quantized' : ''}.onnx`;

console.warn(err);
console.warn(
'Something went wrong during model construction (most likely a missing operation). ' +
'Using `wasm` as a fallback. '
)
return await InferenceSession.create(buffer, {
executionProviders: ['wasm']
});
if (IS_BROWSER || !env.useFS || !env.allowLocalModels || env.useCustomCache) {
let buffer = await getModelFile(pretrained_model_name_or_path, modelFileName, true, options);

return await InferenceSession.create(buffer, sessionOptions);
} else {
let modelPath = await getModelPath(pretrained_model_name_or_path, modelFileName, true, options);
// Download optional external data file
await getModelPath(pretrained_model_name_or_path, `${modelFileName}_data`, false, options);

return await InferenceSession.create(modelPath, sessionOptions);
}
}

Expand Down Expand Up @@ -167,10 +165,10 @@ function validateInputs(session, inputs) {
missingInputs.push(inputName);
continue;
}
// NOTE: When `env.wasm.proxy is true` the tensor is moved across the Worker
// NOTE: When `onnx_env.wasm.proxy is true` the tensor is moved across the Worker
// boundary, transferring ownership to the worker and invalidating the tensor.
// So, in this case, we simply sacrifice a clone for it.
checkedInputs[inputName] = env.wasm.proxy ? tensor.clone() : tensor;
checkedInputs[inputName] = onnx_env.wasm.proxy ? tensor.clone() : tensor;
}
if (missingInputs.length > 0) {
throw new Error(
Expand Down Expand Up @@ -210,7 +208,14 @@ async function sessionRun(session, inputs) {
} catch (e) {
// This usually occurs when the inputs are of the wrong type.
console.error(`An error occurred during model execution: "${e}".`);
console.error('Inputs given to model:', checkedInputs);
// Not log full data, it may cause crash in React Native
console.error(
'Inputs given to model:',
IS_BROWSER ? checkedInputs : Object.fromEntries(
Object.entries(checkedInputs)
.map(([key, tensor]) => [key, { dims: tensor.dims, type: tensor.type }])
)
);
hans00 marked this conversation as resolved.
Show resolved Hide resolved
throw e;
}
}
Expand All @@ -224,7 +229,7 @@ async function sessionRun(session, inputs) {
function replaceTensors(obj) {
for (let prop in obj) {
if (obj[prop] instanceof ONNXTensor) {
obj[prop] = new Tensor(obj[prop]);
obj[prop] = Tensor.fromONNX(obj[prop]);
} else if (typeof obj[prop] === 'object') {
replaceTensors(obj[prop]);
}
Expand Down Expand Up @@ -741,6 +746,7 @@ export class PreTrainedModel extends Callable {
local_files_only = false,
revision = 'main',
model_file_name = null,
session_options = {},
} = {}) {

let options = {
Expand All @@ -751,6 +757,7 @@ export class PreTrainedModel extends Callable {
local_files_only,
revision,
model_file_name,
session_options,
}

const modelName = MODEL_CLASS_TO_NAME_MAPPING.get(this);
Expand Down Expand Up @@ -5524,6 +5531,7 @@ export class PretrainedMixin {
local_files_only = false,
revision = 'main',
model_file_name = null,
session_options = {},
} = {}) {

let options = {
Expand All @@ -5534,6 +5542,7 @@ export class PretrainedMixin {
local_files_only,
revision,
model_file_name,
session_options,
}
config = await AutoConfig.from_pretrained(pretrained_model_name_or_path, options);
if (!options.config) {
Expand Down
15 changes: 12 additions & 3 deletions src/pipelines.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ import {
quantize_embeddings,
} from './utils/tensor.js';
import { RawImage } from './utils/image.js';
import {
fetchBinary
} from './utils/hub.js';


/**
Expand Down Expand Up @@ -2678,7 +2681,7 @@ export class TextToAudioPipeline extends (/** @type {new (options: TextToAudioPi
if (typeof speaker_embeddings === 'string' || speaker_embeddings instanceof URL) {
// Load from URL with fetch
speaker_embeddings = new Float32Array(
await (await fetch(speaker_embeddings)).arrayBuffer()
await (await fetchBinary(speaker_embeddings)).arrayBuffer()
);
}

Expand Down Expand Up @@ -3178,6 +3181,7 @@ export async function pipeline(
cache_dir = null,
local_files_only = false,
revision = 'main',
session_options = {},
model_file_name = null,
} = {}
) {
Expand Down Expand Up @@ -3206,6 +3210,7 @@ export async function pipeline(
cache_dir,
local_files_only,
revision,
session_options,
model_file_name,
}

Expand Down Expand Up @@ -3251,7 +3256,9 @@ async function loadItems(mapping, model, pretrainedOptions) {
if (Array.isArray(cls)) {
promise = new Promise(async (resolve, reject) => {
let e;
for (let c of cls) {
for (let i in cls) {
let isLast = i == cls.length - 1;
let c = cls[i];
if (c === null) {
// If null, we resolve it immediately, meaning the relevant
// class was not found, but it is optional.
Expand All @@ -3262,7 +3269,9 @@ async function loadItems(mapping, model, pretrainedOptions) {
resolve(await c.from_pretrained(model, pretrainedOptions));
return;
} catch (err) {
e = err;
if (!isLast || !err?.message.startsWith('Unsupported model type')) {
e = err;
}
}
}
reject(e);
Expand Down
6 changes: 5 additions & 1 deletion src/tokenizers.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
import { max, min, round } from './utils/maths.js';
import { Tensor } from './utils/tensor.js';

import { env } from './env.js';

import {
PriorityQueue,
TokenLattice,
Expand All @@ -43,6 +45,8 @@ import {

import { Template } from '@huggingface/jinja';

const { backends: { Uint8Array } } = env;


/**
* @typedef {Object} TokenizerProperties Additional tokenizer-specific properties.
Expand Down Expand Up @@ -2047,7 +2051,7 @@ class ByteLevelDecoder extends Decoder {
*/
convert_tokens_to_string(tokens) {
const text = tokens.join('');
const byteArray = new Uint8Array([...text].map(c => this.byte_decoder[c]));
const byteArray = Uint8Array.from([...text].map(c => this.byte_decoder[c]));
const decoded_text = this.text_decoder.decode(byteArray);
return decoded_text;
}
Expand Down
Loading