UNPKG

@huggingface/transformers

Version:

State-of-the-art Machine Learning for the web. Run 🤗 Transformers directly in your browser, with no need for a server!

75 lines (65 loc) • 2.95 kB
import { Pipeline, prepareImages } from './_base.js'; import { Tensor } from '../utils/tensor.js'; /** * @typedef {import('./_base.js').TextImagePipelineConstructorArgs} TextImagePipelineConstructorArgs * @typedef {import('./_base.js').Disposable} Disposable * @typedef {import('./_base.js').ImageInput} ImageInput */ /** * @typedef {Object} ImageToTextSingle * @property {string} generated_text The generated text. * @typedef {ImageToTextSingle[]} ImageToTextOutput * * @typedef {TextImagePipelineConstructorArgs & ImageToTextPipelineCallback & Disposable} ImageToTextPipelineType */ /** * @template T * @typedef {T extends ImageInput[] ? ImageToTextOutput[] : ImageToTextOutput} ImageToTextPipelineResult */ /** * @typedef {<T extends ImageInput | ImageInput[]>(texts: T, options?: Partial<import('../generation/parameters.js').GenerationFunctionParameters>) => Promise<ImageToTextPipelineResult<T>>} ImageToTextPipelineCallback */ /** * Image To Text pipeline using a `AutoModelForVision2Seq`. This pipeline predicts a caption for a given image. * * **Example:** Generate a caption for an image w/ `Xenova/vit-gpt2-image-captioning`. * ```javascript * import { pipeline } from '@huggingface/transformers'; * * const captioner = await pipeline('image-to-text', 'Xenova/vit-gpt2-image-captioning'); * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/cats.jpg'; * const output = await captioner(url); * // [{ generated_text: 'a cat laying on a couch with another cat' }] * ``` * * **Example:** Optical Character Recognition (OCR) w/ `Xenova/trocr-small-handwritten`. * ```javascript * import { pipeline } from '@huggingface/transformers'; * * const captioner = await pipeline('image-to-text', 'Xenova/trocr-small-handwritten'); * const url = 'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/handwriting.jpg'; * const output = await captioner(url); * // [{ generated_text: 'Mr. Brown commented icily.' }] * ``` */ export class ImageToTextPipeline extends /** @type {new (options: TextImagePipelineConstructorArgs) => ImageToTextPipelineType} */ (Pipeline) { async _call(images, generate_kwargs = {}) { const isBatched = Array.isArray(images); const preparedImages = await prepareImages(images); const { pixel_values } = await this.processor(preparedImages); const toReturn = []; for (const batch of pixel_values) { batch.dims = [1, ...batch.dims]; const output = await this.model.generate({ inputs: batch, ...generate_kwargs }); const decoded = this.tokenizer .batch_decode(/** @type {Tensor} */ (output), { skip_special_tokens: true, }) .map((x) => ({ generated_text: x.trim() })); toReturn.push(decoded); } return isBatched ? toReturn : toReturn[0]; } }