Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ __pycache__
node_modules
deno.lock
package-lock.json
*.local.*

# Do not track build artifacts/generated files
packages/*/dist
Expand Down
14 changes: 12 additions & 2 deletions packages/transformers/src/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/

import { pick } from './utils/core.js';
import { getModelJSON } from './utils/hub.js';
import { getModelJSON, maybeAddDeprecatedEnvWarning } from './utils/hub.js';

/**
* @typedef {import('./utils/hub.js').PretrainedOptions} PretrainedOptions
Expand Down Expand Up @@ -531,8 +531,17 @@ export class PretrainedConfig {
*/
static async from_pretrained(
pretrained_model_name_or_path,
{ progress_callback = null, config = null, cache_dir = null, local_files_only = false, revision = 'main' } = {},
{
progress_callback = null,
config = null,
cache_dir = null,
local_files_only = false,
revision = 'main',
env: sessionEnv = {},
} = {},
) {
maybeAddDeprecatedEnvWarning(cache_dir, local_files_only);

if (config && !(config instanceof PretrainedConfig)) {
config = new PretrainedConfig(config);
}
Expand All @@ -545,6 +554,7 @@ export class PretrainedConfig {
cache_dir,
local_files_only,
revision,
env: sessionEnv,
}));
return new this(data);
}
Expand Down
46 changes: 38 additions & 8 deletions packages/transformers/src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,15 @@ if (RUNNING_LOCALLY) {

// Only used for environments with access to file system
const DEFAULT_CACHE_DIR = RUNNING_LOCALLY ? path.join(dirname__, '/.cache/') : null;
const DEFAULT_REMOTE_HOST = globalThis.process?.env?.HF_ENDPOINT ?? 'https://huggingface.co/';

// 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) : DEFAULT_LOCAL_MODEL_PATH;

// Ensure default fetch is called with the correct receiver in browser environments.
const DEFAULT_FETCH = typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : undefined;
const DEFAULT_HF_TOKEN = globalThis.process?.env?.HF_TOKEN ?? globalThis.process?.env?.HF_ACCESS_TOKEN;

/**
* Log levels for controlling output verbosity.
Expand Down Expand Up @@ -202,19 +204,28 @@ export const LogLevel = Object.freeze({
});

/**
* Global variable given visible to users to control execution. This provides users a simple way to configure Transformers.js.
* @typedef {Object} TransformersEnvironment
* @property {string} version This version of Transformers.js.
* @property {{onnx: Partial<import('onnxruntime-common').Env> & { setLogLevel?: (logLevel: number) => void }}} backends Expose environment variables of different backends,
* allowing users to set these variables if they want to.
* @property {number} logLevel The logging level. Use LogLevel enum values. Defaults to LogLevel.ERROR.
* Session-scopable variables that describe the model, task, or resource-loading contract that one pipeline or library must control without affecting others
*
* @typedef {Object} TransformersEnvironmentSession
* @property {boolean} allowRemoteModels Whether to allow loading of remote files, defaults to `true`.
* If set to `false`, it will have the same effect as setting `local_files_only=true` when loading pipelines, models, tokenizers, processors, etc.
* @property {string} remoteHost Host URL to load models from. Defaults to the Hugging Face Hub.
* @property {string} remotePathTemplate Path template to fill in and append to `remoteHost` when loading models.
* @property {boolean} allowLocalModels Whether to allow loading of local files, defaults to `false` if running in-browser, and `true` otherwise.
* If set to `false`, it will skip the local file check and try to load the model from the remote host.
* @property {string} localModelPath Path to load local models from. Defaults to `/models/`.
* @property {(input: string | URL, init?: any) => Promise<any>} fetch The fetch function to use. Defaults to `fetch`.
* @property {string|undefined} hfToken Hugging Face access token to use for requests to the Hugging Face Hub.
*/

/**
* Global variables that describe runtime facts, backend singleton state, or application-owned infrastructure shared across models
*
* @typedef {Object} TransformersEnvironmentGlobal
* @property {string} version This version of Transformers.js.
* @property {{onnx: Partial<import('onnxruntime-common').Env> & { setLogLevel?: (logLevel: number) => void }}} backends Expose environment variables of different backends,
* allowing users to set these variables if they want to.
* @property {number} logLevel The logging level. Use LogLevel enum values. Defaults to LogLevel.ERROR.
* @property {boolean} useFS Whether to use the file system to load files. By default, it is `true` if available.
* @property {boolean} useBrowserCache Whether to use Cache API to cache models. By default, it is `true` if available.
* @property {boolean} useFSCache Whether to use the file system to cache files. By default, it is `true` if available.
Expand All @@ -230,7 +241,12 @@ export const LogLevel = Object.freeze({
* Requires the Cross-Origin Storage Chrome extension: {@link https://chromewebstore.google.com/detail/cross-origin-storage/denpnpcgjgikjpoglpjefakmdcbmlgih}.
* The `experimental_` prefix indicates that the underlying browser API is not yet standardised and may change or be
* removed without a major version bump. For more information, see {@link https://github.com/WICG/cross-origin-storage}.
* @property {(input: string | URL, init?: any) => Promise<any>} fetch The fetch function to use. Defaults to `fetch`.
*/

/**
* Global variable given visible to users to control execution. This provides users a simple way to configure Transformers.js.
*
* @typedef {TransformersEnvironmentGlobal & TransformersEnvironmentSession} TransformersEnvironment
*/

let logLevel = LogLevel.WARNING; // Default log level
Expand All @@ -257,7 +273,7 @@ export const env = {
},
/////////////////// Model settings ///////////////////
allowRemoteModels: true,
remoteHost: 'https://huggingface.co/',
remoteHost: DEFAULT_REMOTE_HOST,
remotePathTemplate: '{model}/resolve/{revision}/',

allowLocalModels: !(IS_BROWSER_ENV || IS_WEBWORKER_ENV || IS_DENO_WEB_RUNTIME), // Default to true for non-web environments, false for web environments
Expand All @@ -280,10 +296,24 @@ export const env = {

/////////////////// Custom fetch /////////////////////
fetch: DEFAULT_FETCH,
hfToken: DEFAULT_HF_TOKEN,

//////////////////////////////////////////////////////
};

/**
* Create a session environment by applying session-scopable overrides to the global environment defaults.
*
* @param {Partial<TransformersEnvironmentSession>} sessionEnv Session-scopable environment overrides.
* @returns {TransformersEnvironment}
*/
export function resolveEnv(sessionEnv = {}) {
return {
...env,
...sessionEnv,
};
}

/**
* @param {Object} obj
* @private
Expand Down
2 changes: 2 additions & 0 deletions packages/transformers/src/models/auto/modeling_auto.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class PretrainedMixin {
dtype = null,
use_external_data_format = null,
session_options = {},
env: sessionEnv = {},
} = {},
) {
const options = {
Expand All @@ -104,6 +105,7 @@ class PretrainedMixin {
dtype,
use_external_data_format,
session_options,
env: sessionEnv,
};
options.config = await AutoConfig.from_pretrained(pretrained_model_name_or_path, options);

Expand Down
10 changes: 9 additions & 1 deletion packages/transformers/src/models/auto/tokenization_auto.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,22 @@ export class AutoTokenizer {
*/
static async from_pretrained(
pretrained_model_name_or_path,
{ progress_callback = null, config = null, cache_dir = null, local_files_only = false, revision = 'main' } = {},
{
progress_callback = null,
config = null,
cache_dir = null,
local_files_only = false,
revision = 'main',
env: sessionEnv = {},
} = {},
) {
const [tokenizerJSON, tokenizerConfig] = await loadTokenizer(pretrained_model_name_or_path, {
progress_callback,
config,
cache_dir,
local_files_only,
revision,
env: sessionEnv,
});

// Some tokenizers are saved with the "Fast" suffix, so we remove that if present.
Expand Down
19 changes: 17 additions & 2 deletions packages/transformers/src/models/modeling_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function registerTaskMappings(mappings) {
MODEL_MAPPING_NAMES = mappings;
}
import { GITHUB_ISSUE_URL } from '../utils/constants.js';
import { getModelJSON } from '../utils/hub.js';
import { getModelJSON, maybeAddDeprecatedEnvWarning } from '../utils/hub.js';
import { Seq2SeqLMOutput } from './modeling_outputs.js';
import {
LogitsProcessorList,
Expand Down Expand Up @@ -275,8 +275,11 @@ export class PreTrainedModel extends Callable {
dtype = null,
use_external_data_format = null,
session_options = {},
env: sessionEnv = {},
} = {},
) {
maybeAddDeprecatedEnvWarning(cache_dir, local_files_only);

const options = {
progress_callback,
config,
Expand All @@ -289,11 +292,19 @@ export class PreTrainedModel extends Callable {
dtype,
use_external_data_format,
session_options,
env: sessionEnv,
};

const modelName = MODEL_CLASS_TO_NAME_MAPPING.get(this);

config = options.config = await AutoConfig.from_pretrained(pretrained_model_name_or_path, options);
config = options.config = await AutoConfig.from_pretrained(pretrained_model_name_or_path, {
progress_callback,
config,
cache_dir,
local_files_only,
revision,
env: sessionEnv,
});

const { typeConfig, textOnly, modelType } = resolveTypeConfig(modelName, config);

Expand All @@ -320,6 +331,10 @@ export class PreTrainedModel extends Callable {
dtype,
device,
model_file_name,
cache_dir,
local_files_only,
revision,
env: sessionEnv,
});

const metadata = await Promise.all(
Expand Down
19 changes: 17 additions & 2 deletions packages/transformers/src/pipelines.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
} from './pipelines/index.js';
import { get_pipeline_files } from './utils/model_registry/get_pipeline_files.js';
import { get_file_metadata } from './utils/model_registry/get_file_metadata.js';
import { maybeAddDeprecatedEnvWarning } from './utils/hub.js';

/**
* @typedef {keyof typeof SUPPORTED_TASKS} TaskType
Expand Down Expand Up @@ -109,8 +110,11 @@ export async function pipeline(
use_external_data_format = null,
model_file_name = null,
session_options = {},
env: sessionEnv = {},
} = {},
) {
maybeAddDeprecatedEnvWarning(cache_dir, local_files_only);

// Apply aliases
// @ts-ignore
task = TASK_ALIASES[task] ?? task;
Expand All @@ -132,15 +136,25 @@ export async function pipeline(

// Determine which files the model needs
const expected_files = await get_pipeline_files(task, model, {
config,
cache_dir,
local_files_only,
revision,
device,
dtype,
model_file_name,
env: sessionEnv,
});

/** @type {import('./utils/core.js').FilesLoadingMap} */
let files_loading = {};
if (progress_callback) {
/** @type {Array<{exists: boolean, size?: number, contentType?: string, fromCache?: boolean}>} */
const metadata = await Promise.all(expected_files.map(async (file) => get_file_metadata(model, file)));
const metadata = await Promise.all(
expected_files.map(async (file) =>
get_file_metadata(model, file, { cache_dir, local_files_only, revision, env: sessionEnv }),
),
);
metadata.forEach((m, i) => {
if (m.exists) {
files_loading[expected_files[i]] = {
Expand All @@ -165,6 +179,7 @@ export async function pipeline(
use_external_data_format,
model_file_name,
session_options,
env: sessionEnv,
};

// Determine which components to load based on the expected files
Expand Down Expand Up @@ -196,7 +211,7 @@ export async function pipeline(
modelPromise,
]);

const results = { task, model: model_loaded };
const results = { task, model: model_loaded, sessionEnv };
if (tokenizer) results.tokenizer = tokenizer;
if (processor) results.processor = processor;

Expand Down
Loading
Loading