Text Generation
Transformers.js
ONNX
llama
webgpu
q4f16
gptq
tool-calling
experimental
conversational
Instructions to use webbrain-one/webbrain-compass-tiny-v2.1 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers.js
How to use webbrain-one/webbrain-compass-tiny-v2.1 with Transformers.js:
// npm i @huggingface/transformers import { pipeline } from '@huggingface/transformers'; // Allocate pipeline const pipe = await pipeline('text-generation', 'webbrain-one/webbrain-compass-tiny-v2.1');
File size: 16,091 Bytes
3632834 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { tensorToDataURL, tensorToImageData } from './tensor-conversion-impl.js';
import { tensorFromGpuBuffer, tensorFromImage, tensorFromMLTensor, tensorFromPinnedBuffer, tensorFromTexture, } from './tensor-factory-impl.js';
import { checkTypedArray, NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP, NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP, } from './tensor-impl-type-mapping.js';
import { calculateSize, tensorReshape } from './tensor-utils-impl.js';
/**
* the implementation of Tensor interface.
*
* @ignore
*/
export class Tensor {
/**
* implementation.
*/
constructor(arg0, arg1, arg2) {
// perform one-time check for BigInt/Float16Array support
checkTypedArray();
let type;
let dims;
if (typeof arg0 === 'object' && 'location' in arg0) {
//
// constructing tensor from specific location
//
this.dataLocation = arg0.location;
type = arg0.type;
dims = arg0.dims;
switch (arg0.location) {
case 'cpu-pinned': {
const expectedTypedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(type);
if (!expectedTypedArrayConstructor) {
throw new TypeError(`unsupported type "${type}" to create tensor from pinned buffer`);
}
if (!(arg0.data instanceof expectedTypedArrayConstructor)) {
throw new TypeError(`buffer should be of type ${expectedTypedArrayConstructor.name}`);
}
this.cpuData = arg0.data;
break;
}
case 'texture': {
if (type !== 'float32') {
throw new TypeError(`unsupported type "${type}" to create tensor from texture`);
}
this.gpuTextureData = arg0.texture;
this.downloader = arg0.download;
this.disposer = arg0.dispose;
break;
}
case 'gpu-buffer': {
if (type !== 'float32' &&
type !== 'float16' &&
type !== 'int32' &&
type !== 'int64' &&
type !== 'uint32' &&
type !== 'uint8' &&
type !== 'bool' &&
type !== 'uint4' &&
type !== 'int4') {
throw new TypeError(`unsupported type "${type}" to create tensor from gpu buffer`);
}
this.gpuBufferData = arg0.gpuBuffer;
this.downloader = arg0.download;
this.disposer = arg0.dispose;
break;
}
case 'ml-tensor': {
if (type !== 'float32' &&
type !== 'float16' &&
type !== 'int32' &&
type !== 'int64' &&
type !== 'uint32' &&
type !== 'uint64' &&
type !== 'int8' &&
type !== 'uint8' &&
type !== 'bool' &&
type !== 'uint4' &&
type !== 'int4') {
throw new TypeError(`unsupported type "${type}" to create tensor from MLTensor`);
}
this.mlTensorData = arg0.mlTensor;
this.downloader = arg0.download;
this.disposer = arg0.dispose;
break;
}
default:
throw new Error(`Tensor constructor: unsupported location '${this.dataLocation}'`);
}
}
else {
//
// constructing tensor of location 'cpu'
//
let data;
let maybeDims;
// check whether arg0 is type or data
if (typeof arg0 === 'string') {
//
// Override: constructor(type, data, ...)
//
type = arg0;
maybeDims = arg2;
if (arg0 === 'string') {
// string tensor
if (!Array.isArray(arg1)) {
throw new TypeError("A string tensor's data must be a string array.");
}
// we don't check whether every element in the array is string; this is too slow. we assume it's correct and
// error will be populated at inference
data = arg1;
}
else {
// numeric tensor
const typedArrayConstructor = NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP.get(arg0);
if (typedArrayConstructor === undefined) {
throw new TypeError(`Unsupported tensor type: ${arg0}.`);
}
if (Array.isArray(arg1)) {
if ((arg0 === 'float16' && typedArrayConstructor === Uint16Array) || arg0 === 'uint4' || arg0 === 'int4') {
// - 'float16':
// When no Float16Array polyfill is used, we cannot create 'float16' tensor from number array.
//
// Throw error here because when user try to use number array as data,
// e.g. new Tensor('float16', [1, 2, 3, 4], dims)), it will actually call
// Uint16Array.from(arg1) which generates wrong data.
//
// - 'uint4' and 'int4':
// Uint8Array.from(arg1) will generate wrong data for 'uint4' and 'int4' tensor.
//
throw new TypeError(`Creating a ${arg0} tensor from number array is not supported. Please use ${typedArrayConstructor.name} as data.`);
}
else if (arg0 === 'uint64' || arg0 === 'int64') {
// use 'as any' here because:
// 1. TypeScript's check on type of 'Array.isArray()' does not work with readonly arrays.
// see https://github.com/microsoft/TypeScript/issues/17002
// 2. TypeScript's check on union type of '(BigInt64ArrayConstructor|BigUint64ArrayConstructor).from()'
// does not accept parameter mapFn.
// 3. parameters of 'SupportedTypedArrayConstructors.from()' does not match the requirement of the union
// type.
// assume 'arg1' is of type "readonly number[]|readonly bigint[]" here.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data = typedArrayConstructor.from(arg1, BigInt);
}
else {
// assume 'arg1' is of type "readonly number[]" here.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data = typedArrayConstructor.from(arg1);
}
}
else if (arg1 instanceof typedArrayConstructor) {
data = arg1;
}
else if (arg1 instanceof Uint8ClampedArray) {
if (arg0 === 'uint8') {
data = Uint8Array.from(arg1);
}
else {
throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`);
}
}
else if (arg0 === 'float16' && arg1 instanceof Uint16Array && typedArrayConstructor !== Uint16Array) {
// when Float16Array is available and data is of type Uint16Array.
// We allow Uint16Array to be passed in as data for 'float16' tensor until Float16Array is generally
// supported in JavaScript environment.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data = new globalThis.Float16Array(arg1.buffer, arg1.byteOffset, arg1.length);
}
else {
throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`);
}
}
}
else {
//
// Override: constructor(data, ...)
//
maybeDims = arg1;
if (Array.isArray(arg0)) {
// only boolean[] and string[] is supported
if (arg0.length === 0) {
throw new TypeError('Tensor type cannot be inferred from an empty array.');
}
const firstElementType = typeof arg0[0];
if (firstElementType === 'string') {
type = 'string';
data = arg0;
}
else if (firstElementType === 'boolean') {
type = 'bool';
// 'arg0' is of type 'boolean[]'. Uint8Array.from(boolean[]) actually works, but typescript thinks this is
// wrong type. We use 'as any' to make it happy.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data = Uint8Array.from(arg0);
}
else {
throw new TypeError(`Invalid element type of data array: ${firstElementType}.`);
}
}
else if (arg0 instanceof Uint8ClampedArray) {
type = 'uint8';
data = Uint8Array.from(arg0);
}
else {
// get tensor type from TypedArray
const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(arg0.constructor);
if (mappedType === undefined) {
throw new TypeError(`Unsupported type for tensor data: ${arg0.constructor}.`);
}
type = mappedType;
data = arg0;
}
}
// type and data is processed, now processing dims
if (maybeDims === undefined) {
// assume 1-D tensor if dims omitted
maybeDims = [data.length];
}
else if (!Array.isArray(maybeDims)) {
throw new TypeError("A tensor's dims must be a number array");
}
dims = maybeDims;
this.cpuData = data;
this.dataLocation = 'cpu';
}
// perform check on dims
const size = calculateSize(dims);
// if data is on CPU, check whether data length matches tensor size
if (this.cpuData && size !== this.cpuData.length) {
if ((type === 'uint4' || type === 'int4') && Math.ceil(size / 2) === this.cpuData.length) {
// for (u)int4, the data length is half of the tensor size. So we check this special case when size is odd.
}
else {
throw new Error(`Tensor's size(${size}) does not match data length(${this.cpuData.length}).`);
}
}
this.type = type;
this.dims = dims;
this.size = size;
}
// #endregion
// #region factory
static async fromImage(image, options) {
return tensorFromImage(image, options);
}
static fromTexture(texture, options) {
return tensorFromTexture(texture, options);
}
static fromGpuBuffer(gpuBuffer, options) {
return tensorFromGpuBuffer(gpuBuffer, options);
}
static fromMLTensor(mlTensor, options) {
return tensorFromMLTensor(mlTensor, options);
}
static fromPinnedBuffer(type, buffer, dims) {
return tensorFromPinnedBuffer(type, buffer, dims);
}
// #endregion
// #region conversions
toDataURL(options) {
return tensorToDataURL(this, options);
}
toImageData(options) {
return tensorToImageData(this, options);
}
// #endregion
// #region properties
get data() {
this.ensureValid();
if (!this.cpuData) {
throw new Error('The data is not on CPU. Use `getData()` to download GPU data to CPU, ' +
'or use `texture` or `gpuBuffer` property to access the GPU data directly.');
}
return this.cpuData;
}
get location() {
return this.dataLocation;
}
get texture() {
this.ensureValid();
if (!this.gpuTextureData) {
throw new Error('The data is not stored as a WebGL texture.');
}
return this.gpuTextureData;
}
get gpuBuffer() {
this.ensureValid();
if (!this.gpuBufferData) {
throw new Error('The data is not stored as a WebGPU buffer.');
}
return this.gpuBufferData;
}
get mlTensor() {
this.ensureValid();
if (!this.mlTensorData) {
throw new Error('The data is not stored as a WebNN MLTensor.');
}
return this.mlTensorData;
}
// #endregion
// #region methods
async getData(releaseData) {
this.ensureValid();
switch (this.dataLocation) {
case 'cpu':
case 'cpu-pinned':
return this.data;
case 'texture':
case 'gpu-buffer':
case 'ml-tensor': {
if (!this.downloader) {
throw new Error('The current tensor is not created with a specified data downloader.');
}
if (this.isDownloading) {
throw new Error('The current tensor is being downloaded.');
}
try {
this.isDownloading = true;
const data = await this.downloader();
this.downloader = undefined;
this.dataLocation = 'cpu';
this.cpuData = data;
if (releaseData && this.disposer) {
this.disposer();
this.disposer = undefined;
}
return data;
}
finally {
this.isDownloading = false;
}
}
default:
throw new Error(`cannot get data from location: ${this.dataLocation}`);
}
}
dispose() {
if (this.isDownloading) {
throw new Error('The current tensor is being downloaded.');
}
if (this.disposer) {
this.disposer();
this.disposer = undefined;
}
this.cpuData = undefined;
this.gpuTextureData = undefined;
this.gpuBufferData = undefined;
this.mlTensorData = undefined;
this.downloader = undefined;
this.isDownloading = undefined;
this.dataLocation = 'none';
}
// #endregion
// #region tensor utilities
ensureValid() {
if (this.dataLocation === 'none') {
throw new Error('The tensor is disposed.');
}
}
reshape(dims) {
this.ensureValid();
if (this.downloader || this.disposer) {
throw new Error('Cannot reshape a tensor that owns GPU resource.');
}
return tensorReshape(this, dims);
}
}
//# sourceMappingURL=tensor-impl.js.map |