3 điểm bởi GN⁺ 2024-04-13 | 1 bình luận | Chia sẻ qua WhatsApp
  • Transformers.js là thư viện để chạy các mô hình 🤗 Transformers trong trình duyệt mà không cần máy chủ, hướng tới tính năng tương đương và API tương tự với transformers Python của Hugging Face
  • Việc chạy mô hình sử dụng ONNX Runtime; các mô hình huấn luyện sẵn PyTorch, TensorFlow, JAX có thể được chuyển đổi sang ONNX bằng 🤗 Optimum để sử dụng
  • Với API pipeline, có thể gọi các tác vụ như phân tích cảm xúc theo cách tương tự Python; có thể chỉ định ID mô hình hoặc đường dẫn làm đối số thứ hai để chọn mô hình khác
  • Mặc định khi chạy trong trình duyệt là CPU dựa trên WASM; có thể chọn chạy WebGPU bằng device: 'webgpu', nhưng WebGPU API vẫn còn mang tính thử nghiệm trên nhiều trình duyệt
  • Trong môi trường hạn chế tài nguyên như trình duyệt web, có thể chọn kiểu dữ liệu như "fp32", "fp16", "q8", "q4" bằng dtype để điều chỉnh băng thông và hiệu năng

Chạy Transformers trong trình duyệt

  • Transformers.js là thư viện được thiết kế để chạy trực tiếp 🤗 Transformers trong trình duyệt mà không cần máy chủ
  • Hướng tới trải nghiệm sử dụng tương đương về chức năng với thư viện Python transformers của Hugging Face, cho phép chạy cùng các mô hình huấn luyện sẵn với API rất giống nhau
  • Các tác vụ được hỗ trợ trải rộng trên nhiều modality
    • Xử lý ngôn ngữ tự nhiên: phân loại văn bản, nhận dạng thực thể có tên, hỏi đáp, mô hình hóa ngôn ngữ, tóm tắt, dịch, trắc nghiệm, sinh văn bản
    • Thị giác máy tính: phân loại ảnh, phát hiện đối tượng, phân đoạn, ước lượng độ sâu
    • Âm thanh: nhận dạng giọng nói tự động, phân loại âm thanh, chuyển văn bản thành giọng nói
    • Đa phương thức: embedding, phân loại âm thanh zero-shot, phân loại ảnh zero-shot, phát hiện đối tượng zero-shot

Cách chạy và chuyển đổi mô hình

Cài đặt và sử dụng trong trình duyệt

  • Gói NPM được cài đặt bằng lệnh sau
npm i @huggingface/transformers
  • Cũng có thể dùng với vanilla JS mà không cần bundler, bằng cách import dưới dạng ES Modules qua CDN hoặc hosting tĩnh
<script type="module">
    import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>

API pipeline tương tự Python

  • API pipeline là cách dễ nhất để chạy mô hình trong thư viện, bằng cách gộp mô hình huấn luyện sẵn, tiền xử lý đầu vào và hậu xử lý đầu ra
  • Tương tự ví dụ phân tích cảm xúc của Python transformers, trong JavaScript cũng có thể tạo pipeline('sentiment-analysis'), nhập văn bản và nhận kết quả
import { pipeline } from '@huggingface/transformers';

const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
  • Để dùng mô hình khác, hãy chỉ định ID mô hình hoặc đường dẫn làm đối số thứ hai của hàm pipeline
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/bert-base-multilingual-uncased-sentiment'
);

CPU, WebGPU và tùy chọn lượng tử hóa

  • Giá trị mặc định khi chạy trong trình duyệt là chạy trên CPU dựa trên WASM
  • Để chạy trên GPU, đặt device: 'webgpu'
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    device: 'webgpu',
  }
);
  • Thông tin chi tiết về WebGPU có trong WebGPU guide
  • WebGPU API vẫn còn mang tính thử nghiệm trên nhiều trình duyệt, nên nếu gặp vấn đề, người dùng được hướng dẫn gửi báo cáo lỗi WebGPU
  • Trong môi trường trình duyệt web hạn chế tài nguyên, nên dùng mô hình đã lượng tử hóa
    • Chọn kiểu dữ liệu của mô hình bằng tùy chọn dtype
    • Các lựa chọn phổ biến là "fp32" mặc định của WebGPU, "fp16", "q8" mặc định của WASM, "q4"
    • Thông tin chi tiết có trong quantization guide
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    dtype: 'q4',
  }
);

Cấu hình tùy chỉnh

import { env } from '@huggingface/transformers';

env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
  • Toàn bộ cấu hình khả dụng có trong API Reference
  • Khi chuyển đổi mô hình PyTorch sang ONNX, khuyến nghị dùng cách một lệnh với Optimum

Phạm vi tác vụ và mô hình được hỗ trợ

  • Để tìm mô hình tương thích trên Hugging Face Hub, có thể lọc theo tag thư viện transformers.js
  • Các tác vụ được hỗ trợ trải rộng trên xử lý ngôn ngữ tự nhiên, thị giác, âm thanh, đa phương thức và học tăng cường; một số tác vụ vẫn chưa được hỗ trợ
    • Trong xử lý ngôn ngữ tự nhiên, hỗ trợ fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification, feature-extraction, v.v.
    • Trong thị giác, hỗ trợ background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection, image-feature-extraction, v.v.
    • Trong âm thanh, hỗ trợ audio-classification, automatic-speech-recognition, text-to-speech
    • Trong đa phương thức, hỗ trợ document-question-answering, image-to-text, zero-shot audio/image classification, zero-shot object detection, v.v.
  • Các tác vụ chưa được hỗ trợ cũng được nêu rõ
    • table-question-answering, mask-generation, video-classification, unconditional-image-generation
    • audio-to-audio, tabular-classification, tabular-regression
    • text-to-image, visual-question-answering
  • Danh sách kiến trúc mô hình được hỗ trợ bao gồm nhiều họ mô hình như BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything, ViT
  • Nếu tác vụ hoặc mô hình mong muốn không có trong danh sách hoặc chưa được hỗ trợ, có thể mở yêu cầu tính năng

1 bình luận

 
GN⁺ 2024-04-13
Ý kiến trên Hacker News
  • Thư viện này thật sự rất tuyệt. Việc dựng một demo nhanh cực kỳ dễ, nên tôi đã dùng vài lần trong Observable notebook
    CLIP trên trình duyệt: https://observablehq.com/@simonw/openai-clip-in-a-browser
    Phát hiện đối tượng trong ảnh bằng detra-resnet-50: https://observablehq.com/@simonw/detect-objects-in-images
    Ban đầu kích thước mô hình có vẻ là một hạn chế, nhưng cũng có khá nhiều ứng dụng mà việc yêu cầu người dùng có laptop tốt và kết nối ổn chờ khoảng 30 giây để tải không phải là điều vô lý
    Bản phát hành mới nhất đã thêm hỗ trợ lượng tử hóa embedding nhị phân, nên tôi rất muốn thử: https://github.com/xenova/transformers.js/releases/tag/2.17....
    • Embedding nhị phân có lẽ sẽ cần thêm bước sắp xếp lại thứ hạng, nhưng thử nghiệm chắc sẽ thú vị
      Tôi đã tạo sẵn gói npm cho transformers.js v3 và chắc cần cập nhật. Không chắc tính năng này đã được đưa vào chưa
      Tôi chủ yếu duy trì một fork để chạy được trên bun, và khi v3 được phát hành thì sẽ hỗ trợ bun đúng nghĩa. Tuy vậy WebGPU sẽ không hoạt động, nhưng đó là tính năng tùy chọn
      [Sửa: nếu muốn dùng thì DM. Tôi không muốn quảng bá fork]
  • Tôi đang dùng thư viện này để tạo embedding gte-small(~0,07GB) và lưu vào Upstash Vector
    Chỉ có 384 chiều nhưng hoạt động tốt đáng ngạc nhiên với văn bản ở cấp đoạn. Trên bảng xếp hạng nó còn đứng cao hơn text-embedding-ada-002
    https://huggingface.co/spaces/mteb/leaderboard
  • Podcast Syntax gần đây đã có một tập nói về Transformers.js và nhà phát triển của nó
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js là một thư viện thật sự tuyệt vời
    Tôi đã làm một webapp nhỏ để xóa nền ảnh bằng mô hình RMBG1.4 của BRIA AI: https://aether.nco.dev
    Điểm rất hay là không cần gửi dữ liệu qua API và vẫn chạy được trên smartphone. Tôi nghĩ sắp tới sẽ có nhiều dự án dùng nó cho các mô hình nhỏ về thị giác, ngôn ngữ và các tiện ích khác (ước lượng độ sâu, xóa nền, v.v.), và tương lai của web trông rất sáng
    Tôi cũng đang làm dự án tiếp theo, và chắc chắn sẽ lại dùng transformers.js ở đó
    • Tôi đang dùng cho một dự án đơn giản: https://github.com/sroussey/ellmers
      Kế hoạch là thử nghiệm embedding và các chiến lược tìm kiếm cho nhiều chiến lược RAG dùng trên server hoặc ứng dụng Electron
  • Rất tuyệt, nhưng đáng tiếc là tính thực dụng có vẻ khá thấp. Các mô hình nhìn chung khá lớn, nên dù trình duyệt có thể chạy được thì quá trình đưa chúng tới trình duyệt cũng cần một trong hai điều sau
    1. Tải xuống dung lượng lớn mỗi lần truy cập website
    2. Tải xuống dung lượng lớn và dùng nhiều không gian lưu trữ cho mỗi website dùng mô hình lớn. Ví dụ 150 website × mô hình 800MB sẽ dùng 120GB dung lượng lưu trữ
      Cả hai đều không ổn
      Về dài hạn, có lẽ hướng đúng là trình duyệt tích hợp sẵn một số mô hình và expose chúng qua API web được chuẩn hóa, nhưng tôi chưa nghe nói có nỗ lực nào như vậy đang diễn ra

Các model được cache theo từng miền (dùng Web Cache API), nên không cần tải lại mỗi lần tải trang. Nếu muốn duy trì model xuyên miền, có thể dùng thư viện này để tạo tiện ích mở rộng trình duyệt
Phần vừa nói cuối cùng là một nỗ lực đang diễn ra, nhưng chưa đến giai đoạn có thể nói thêm

  • Đây gần như là cùng một vấn đề đã gây khổ cho game web kể từ các demo Unreal/Unity asm.js đầu tiên 10 năm trước, và trong thời gian đó hầu như không có tiến triển đáng kể theo hướng giải quyết
    Rất khó để xây dựng một webapp thực tế cần dữ liệu cỡ gigabyte ở phía client. Không có cách ổn định nào để đảm bảo dữ liệu sẽ nằm trong cache lâu như người dùng muốn, và ngay cả khi có thể cache ổn định, chính sách phân vùng cache của trình duyệt cũng khiến mỗi trang dùng cùng một model phải tải xuống và chiếm dung lượng lưu trữ trùng lặp
  • Model có dung lượng dưới 80MB, phần còn lại là LLM nên nằm ngoài phạm vi. Whisper là 40MB, embedding là 23MB
    Những phần trong bình luận gốc như “trông rất không thực tế”, “model nhìn chung khá lớn”, “150 trang × model 800MB” có vẻ như tự gắn kèm điều kiện rằng người viết chưa hiểu đầy đủ
  • Một số model khá nhỏ, nên đáng để chạy on-device hơn là gửi toàn bộ dữ liệu lên server để xử lý
    Một lợi thế lớn khác là transformers cũng chạy được trên Node.js. Việc tạo môi trường chạy dễ hơn nhiều so với việc ghép cho đúng tổ hợp kỳ quặc giữa Python và các dependency của nó
  • Đây không chỉ là vấn đề riêng của trình duyệt, mà là vấn đề cốt lõi của xử lý AI on-device
    Có lẽ tình hình sẽ khá hơn khi hệ điều hành bắt đầu cài sẵn model và các nhà cung cấp trình duyệt cũng cung cấp API có thể sử dụng
    Dù vậy, với hầu hết tác vụ, rất có khả năng model host trên cloud vẫn luôn tốt hơn nhiều
  • Vậy giờ có thể tạo plugin trình duyệt để chọn hết xe đạp hoặc cây cầu trong CAPTCHA của Google chưa?
  • Không thể huấn luyện được sao? Vài năm trước tôi từng thử tạo và huấn luyện một mạng nơ-ron nhỏ trong trình duyệt, và giờ tôi tò mò liệu cách đó có chạy tốt hơn với một custom transformer nhỏ không
    • Về lý thuyết thì chắc chắn là có thể, nhưng có lẽ vấn đề hiệu năng là lý do nó chưa được triển khai
      Có một benchmark embedding WebGPU trên Hugging Face Space, có thể dùng để ước lượng hoạt động forward pass: https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
      Bản thân nó khá ấn tượng, nhưng huấn luyện với độ trễ đó có vẻ sẽ rất khổ. Ở fp16, batch 32, độ dài chuỗi 512, forward pass của model 22 triệu tham số mất khoảng 500ms
  • Như vậy chẳng phải cũng mở ra khả năng chạy các model kiểu này trong serverless function Node.js sao?
    Có vẻ chắc chắn cũng sẽ có tiềm năng cho dự đoán theo nhu cầu
  • Có hỗ trợ tăng tốc Apple Silicon không?