Transformers.js

repository·main·Indexed 12 days ago

https://github.com/huggingface/transformers.js

A JavaScript library for running state-of-the-art machine learning models directly in the browser or Node.js using ONNX Runtime. It provides a pipeline API functionally equivalent to the Hugging Face Python transformers library, supporting NLP, Vision, and Audio tasks. Features include WebGPU acceleration, model quantization via the dtype parameter (e.g., fp32, fp16, q8, q4), and support for a wide range of model families including Llama, Mistral, and Whisper.

Tokens
34.4K
Snippets
101
Records
129
Agent score
96%

What's inside Transformers.js

  1. Supported models in Transformers.js

    main

    Transformers.js supports a wide variety of pre-trained models across different tasks, including language modeling, vision, audio, and time-series forecasting. Key model families supported include:

    • Language Models: MT5, NanoChat, Nemotron, Nemotron-H, NeoBERT, OLMo (including OLMo2, OLMo3, and Olmo Hybrid), OpenELM, OPT, Phi (including Phi3 and Phi3V).
    • Vision & Multimodal: OWL-ViT, OWLv2, PaliGemma, PVT.
    • Audio: NLLB (Translation), Nougat (Document Understanding), Parakeet (ASR), PyAnnote (Speaker Diarization).
    • Time Series: PatchTSMixer, PatchTST.

    For specific model details, refer to the individual model documentation links provided in the official repository.

  2. Best practices for running Transformers.js in React

    main

    When integrating Transformers.js into a React application, follow these two architectural patterns to ensure a smooth user experience:

    1. Use Web Workers: ML inference is computationally intensive and can block the main UI thread. Offload the loading and running of pipelines to a separate Web Worker thread.
    2. Lazy Loading: Since models can be very large (often >1 GB), do not load them on application startup. Instead, trigger the model download and initialization only when the user performs a specific action (e.g., clicking a "Translate" button).

    To implement this, you can use a singleton pattern within your worker script to ensure the pipeline instance is created only once and reused for subsequent calls.

  3. How the `pipeline` API works

    main

    The pipeline() API is a high-level abstraction designed to simplify model inference.

    Mental Model:

    1. Initialization: You call pipeline(task, model_id, options). This loads the model, tokenizer, and any necessary processors.
    2. Execution: The returned object is a function. When called with input (string, array of strings, or audio URL), it automatically performs:
      • Preprocessing: Converting raw input into the format the model expects (e.g., tokenization for text, resampling for audio).
      • Inference: Running the model through the ONNX runtime.
      • Postprocessing: Converting model outputs (logits/tensors) back into human-readable formats (e.g., labels, text, or translations).

    If you need more granular control over the individual components (tokenizer, model, or processor) without the pipeline abstraction, you should use the AutoModel, AutoTokenizer, or AutoProcessor classes instead.

  4. Initialize a React project with Vite

    main

    To build a React application for Transformers.js, use Vite to set up the project environment. This provides a fast development server and build tool.

    1. Run the Vite initializer:
      npm create vite@latest react-translator -- --template react
    2. Navigate to the directory and install dependencies:
      cd react-translator
      npm install
    3. Start the development server:
      npm run dev
    npm create vite@latest react-translator -- --template react
    cd react-translator
    npm install
    npm run dev
  5. Use the pipeline API for machine learning tasks

    main

    The pipeline API is the easiest way to run models. It groups a pretrained model with the necessary preprocessing and postprocessing. The API is functionally equivalent to the Hugging Face Python transformers library.

    To use a default model for a specific task (e.g., 'sentiment-analysis'), await the pipeline function and then call the resulting object with your input.

    import { pipeline } from '@huggingface/transformers';
    
    // Allocate a pipeline for sentiment-analysis
    const pipe = await pipeline('sentiment-analysis');
    
    const out = await pipe('I love transformers!');
    // Output example: [{'label': 'POSITIVE', 'score': 0.999817686}]
  6. Deploy a Next.js Transformers.js App to Hugging Face Spaces

    main

    To deploy a server-side Next.js application to Hugging Face Spaces:

    1. Create a Dockerfile in your project root (use a template suitable for Next.js).
    2. Create a new Space on Hugging Face and select the Docker SDK.
    3. Upload your project files (excluding node_modules and .next).
    4. Add a YAML configuration block to the top of your README.md to define the Space metadata:
    ---
    title: Next Server Example App
    emoji: 🔥
    colorFrom: yellow
    colorTo: red
    sdk: docker
    pinned: false
    app_port: 3000
    ---
  7. Setup Node.js for Audio Processing with Transformers.js

    main

    To perform audio processing in a Node.js environment, you must manually handle audio decoding because the Web Audio API (AudioContext) is not available in Node.js. This guide uses the wavefile library to convert .wav files into the Float32Array format required by Transformers.js pipelines.

    Prerequisites

    • Node.js version 18+
    • npm version 9+

    Installation

    Initialize your project and install the necessary dependencies:

    npm init -y
    npm i @huggingface/transformers
    npm i wavefile

    Note: Ensure you add "type": "module" to your package.json to use ECMAScript modules.

  8. Enable WebGPU acceleration in Transformers.js

    main

    To use WebGPU for high-performance GPU-accelerated computations in the browser, pass { device: 'webgpu' } as an option when initializing a pipeline using the pipeline function. This leverages ONNX Runtime Web to interact directly with the system's GPU.

    Note on Browser Support: As of late 2024, WebGPU support is approximately 70%. If WebGPU is not working, you may need to enable it via feature flags:

    • Firefox: Enable dom.webgpu.enabled.
    • Safari: Enable the WebGPU feature flag.
    • Older Chromium browsers: Enable the enable-unsafe-webgpu flag.
    import { pipeline } from "@huggingface/transformers";
    
    const classifier = await pipeline(
      "image-classification",
      "onnx-community/mobilenetv4_conv_small.e2400_r224_in1k",
      { device: "webgpu" },
    );
  9. Implement a Singleton Pipeline for Next.js Server-side Inference

    main

    To avoid re-initializing the model on every request (which is expensive), use a Singleton pattern. This allows for lazy construction of the pipeline and ensures the model is cached in memory.

    In Next.js development mode, it is recommended to attach the singleton instance to the global object. This prevents the pipeline from being destroyed and re-downloaded during hot reloads.

    Implementation Pattern

    1. Define a class with static task, static model, and a static async getInstance() method.
    2. Use pipeline(task, model, { progress_callback }) inside getInstance().
    3. In development (process.env.NODE_ENV !== 'production'), check global.PipelineSingleton to preserve the instance across reloads.
    import { pipeline } from "@huggingface/transformers";
    
    const P = () =>
      class PipelineSingleton {
        static task = "text-classification";
        static model = "Xenova/distilbert-base-uncased-finetuned-sst-2-english";
        static instance = null;
    
        static async getInstance(progress_callback = null) {
          if (this.instance === null) {
            this.instance = pipeline(this.task, this.model, {
              progress_callback,
            });
          }
          return this.instance;
        }
      };
    
    let PipelineSingleton;
    if (process.env.NODE_ENV !== "production") {
      if (!global.PipelineSingleton) {
        global.PipelineSingleton = P();
      }
      PipelineSingleton = global.PipelineSingleton;
    } else {
      PipelineSingleton = P();
    }
    export default PipelineSingleton;
  10. Track model download progress

    main

    Models are downloaded on first use. You can track this progress using model.availability() and model.createSessionWithProgress(callback).

    • availability() returns "unavailable" if the browser doesn't support Transformers.js, or "downloadable" if the model needs to be fetched.
    • createSessionWithProgress accepts a callback receiving a progress value (0 to 1).
    import { streamText } from "ai";
    import { transformersJS } from "@browser-ai/transformers-js";
    
    const model = transformersJS("HuggingFaceTB/SmolLM2-360M-Instruct");
    const availability = await model.availability();
    
    if (availability === "unavailable") {
      console.log("Browser doesn't support Transformers.js");
    } else if (availability === "downloadable") {
      await model.createSessionWithProgress(({ progress }) => {
        console.log(`Download progress: ${Math.round(progress * 100)}%`);
      });
    }
    
    // Model is ready
    const result = streamText({ model, prompt: "Hello!" });