Skip to content

Introduce @huggingface/transformers-llguidance#1721

Open
nico-martin wants to merge 5 commits into
feat/response_formatfrom
feat/transformers-llguidance
Open

Introduce @huggingface/transformers-llguidance#1721
nico-martin wants to merge 5 commits into
feat/response_formatfrom
feat/transformers-llguidance

Conversation

@nico-martin

Copy link
Copy Markdown
Collaborator

This PR adds a new @huggingface/transformers-llguidance package that wraps llguidance response formats into the generation hooks already supported by Transformers.js:

  • logits_processor to mask invalid next tokens during generation
  • stopping_criteria to stop once the llguidance interpreter reaches completion

The package currently exposes LlguidanceConstraint.fromResponseFormat(tokenizer, response_format, loadOptions?), which accepts llguidance response formats such as json_schema, json_object, and regex, then returns the objects that can be passed directly into Transformers.js generation.

Closes #1328.

Why

This keeps constrained generation outside the core @huggingface/transformers package while still integrating with its existing generation extension points. It also gives us a small package boundary for the llguidance dependency and its WASM loading behavior.

Demo

import { pipeline } from "@huggingface/transformers";
import { LlguidanceConstraint } from "@huggingface/transformers-llguidance";

const pipe = await pipeline("text-generation", "onnx-community/gemma-4-E2B-it-ONNX", {
  device: "webgpu",
  dtype: "q4f16",
});

const { logits_processor, stopping_criteria } =
  await LlguidanceConstraint.fromResponseFormat(pipe.tokenizer, {
    type: "json_schema",
    json_schema: {
      type: "object",
      properties: {
        answer: { type: "string" },
      },
      required: ["answer"],
      additionalProperties: false,
    },
  });

const output = await pipe(
  [
    {
      role: "system",
      content: "You are a helpful assistant.",
    },
    { role: "user", content: "Answer with a short friendly greeting." },
  ],
  {
    max_new_tokens: 64,
    logits_processor,
    stopping_criteria,
  },
);

console.log("=== ANSWER ===");
console.log(JSON.parse(output[0].generated_text.pop().content));

await pipe.dispose();

Loading And Caching

The package delegates to llguidance for creating the interpreter, but preloads the llguidance WASM assets through Transformers.js WASM helpers when possible. This means browser-like runtimes can reuse the same cache path controlled by env.useWasmCache instead of forcing llguidance to fetch its WASM assets independently.

The loading behavior is:

  • If useWasmCache is disabled, the runtime is Node-like, or the caller provides wasmFactory, load directly through llguidance.
  • Otherwise, preload the WASM binary and factory through Transformers.js cache-aware helpers.
  • If preloading fails, fall back to the original llguidance loading options instead of failing generation setup.

Open Question

llguidance-js currently lives under my own user:

Should we keep it there for now, move it into the Transformers.js package/workspace, or publish/maintain it under the Hugging Face org?

@nico-martin nico-martin requested a review from xenova July 11, 2026 06:43
@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants