3P by GN⁺ | ★ favorite | 댓글 1개
  • Transformers.js는 서버 없이 브라우저에서 🤗 Transformers 모델을 실행하기 위한 라이브러리로, Hugging Face의 Python transformers와 기능적으로 동등하고 유사한 API를 목표로 함
  • 모델 실행에는 ONNX Runtime을 사용하며, PyTorch·TensorFlow·JAX 사전학습 모델은 🤗 Optimum으로 ONNX 변환해 사용할 수 있음
  • pipeline API로 감성 분석 같은 작업을 Python과 비슷한 방식으로 호출하며, 모델 ID나 경로를 두 번째 인자로 지정해 다른 모델을 선택할 수 있음
  • 브라우저 기본 실행은 WASM 기반 CPU이며, device: 'webgpu'로 WebGPU 실행을 선택할 수 있지만 WebGPU API는 여러 브라우저에서 아직 실험적임
  • 웹 브라우저처럼 자원이 제한된 환경에서는 dtype으로 "fp32", "fp16", "q8", "q4" 같은 데이터 타입을 선택해 대역폭과 성능을 조정할 수 있음

브라우저에서 실행하는 Transformers

  • Transformers.js는 서버 없이 브라우저에서 🤗 Transformers를 직접 실행하도록 설계된 라이브러리임
  • Hugging Face의 Python transformers 라이브러리와 기능적으로 동등한 사용 경험을 목표로 하며, 같은 사전학습 모델을 매우 유사한 API로 실행할 수 있음
  • 지원 작업은 여러 모달리티에 걸쳐 있음
    • 자연어 처리: 텍스트 분류, 개체명 인식, 질의응답, 언어 모델링, 요약, 번역, 객관식, 텍스트 생성
    • 컴퓨터 비전: 이미지 분류, 객체 탐지, 세그멘테이션, 깊이 추정
    • 오디오: 자동 음성 인식, 오디오 분류, 텍스트 음성 변환
    • 멀티모달: 임베딩, 제로샷 오디오 분류, 제로샷 이미지 분류, 제로샷 객체 탐지

실행 방식과 모델 변환

설치와 브라우저 사용

  • NPM 패키지는 다음 명령으로 설치함
npm i @huggingface/transformers
  • 번들러 없이 vanilla JS에서도 사용할 수 있으며, CDN이나 정적 호스팅을 통해 ES Modules로 가져올 수 있음
<script type="module">
    import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@4.2.0';
</script>

Python과 비슷한 pipeline API

  • pipeline API는 사전학습 모델, 입력 전처리, 출력 후처리를 묶어 라이브러리에서 모델을 실행하는 가장 쉬운 방법임
  • Python transformers의 감성 분석 예제와 유사하게 JavaScript에서도 pipeline('sentiment-analysis')를 만들고 텍스트를 입력해 결과를 받을 수 있음
import { pipeline } from '@huggingface/transformers';

const pipe = await pipeline('sentiment-analysis');
const out = await pipe('I love transformers!');
// [{'label': 'POSITIVE', 'score': 0.999817686}]
  • 다른 모델을 쓰려면 pipeline 함수의 두 번째 인자로 모델 ID 또는 경로를 지정함
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/bert-base-multilingual-uncased-sentiment'
);

CPU, WebGPU, 양자화 옵션

  • 브라우저 실행 기본값은 WASM 기반 CPU 실행임
  • GPU에서 실행하려면 device: 'webgpu'를 설정함
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    device: 'webgpu',
  }
);
  • WebGPU 관련 자세한 내용은 WebGPU guide에 있음
  • WebGPU API는 여러 브라우저에서 아직 실험적이므로 문제가 발생하면 WebGPU 버그 리포트를 제출하도록 안내함
  • 자원이 제한된 웹 브라우저 환경에서는 양자화된 모델 사용이 권장됨
    • dtype 옵션으로 모델 데이터 타입을 선택함
    • 일반적인 선택지는 "fp32" WebGPU 기본값, "fp16", "q8" WASM 기본값, "q4"
    • 자세한 내용은 quantization guide에 있음
const pipe = await pipeline(
  'sentiment-analysis',
  'Xenova/distilbert-base-uncased-finetuned-sst-2-english',
  {
    dtype: 'q4',
  }
);

커스텀 설정

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

env.localModelPath = '/path/to/models/';
env.allowRemoteModels = false;
env.backends.onnx.wasm.wasmPaths = '/path/to/files/';
  • 사용 가능한 전체 설정은 API Reference에 있음
  • PyTorch 모델을 ONNX로 변환할 때는 Optimum을 사용하는 단일 명령 방식이 권장됨

지원 작업과 모델 범위

  • Hugging Face Hub에서 호환 모델을 찾으려면 transformers.js 라이브러리 태그로 필터링할 수 있음
  • 지원 작업은 자연어 처리, 비전, 오디오, 멀티모달, 강화학습에 걸쳐 있으며 일부 작업은 아직 지원되지 않음
    • 자연어 처리에서는 fill-mask, question-answering, summarization, text-classification, text-generation, token-classification, translation, zero-shot-classification, feature-extraction 등이 지원됨
    • 비전에서는 background-removal, depth-estimation, image-classification, image-segmentation, image-to-image, object-detection, image-feature-extraction 등이 지원됨
    • 오디오에서는 audio-classification, automatic-speech-recognition, text-to-speech가 지원됨
    • 멀티모달에서는 document-question-answering, image-to-text, zero-shot audio/image classification, zero-shot object detection 등이 지원됨
  • 아직 지원되지 않는 작업도 명시되어 있음
    • table-question-answering, mask-generation, video-classification, unconditional-image-generation
    • audio-to-audio, tabular-classification, tabular-regression
    • text-to-image, visual-question-answering
  • 지원 모델 아키텍처 목록에는 BERT, BART, CLIP, DistilBERT, Whisper, Llama, Qwen, Gemma, Phi, Segment Anything, ViT 등 다수의 모델 계열이 포함됨
  • 원하는 작업이나 모델이 목록에 없거나 아직 지원되지 않으면 기능 요청을 열 수 있음

댓글과 토론

Hacker News 의견들
  • 이 라이브러리는 정말 멋짐. 빠른 데모를 띄우기가 엄청 쉬워서 Observable 노트북에서 몇 번 써봤음
    브라우저에서 CLIP: https://observablehq.com/@simonw/openai-clip-in-a-browser
    detra-resnet-50으로 이미지 객체 탐지: https://observablehq.com/@simonw/detect-objects-in-images
    모델 크기가 처음엔 제약처럼 느껴지지만, 좋은 노트북과 연결을 가진 사용자에게 로딩에 30초 정도 기다려야 한다고 하는 게 말이 안 되는 수준은 아닌 앱도 꽤 있음
    최신 릴리스에는 바이너리 임베딩 양자화 지원이 추가돼서 꼭 시험해보고 싶음: https://github.com/xenova/transformers.js/releases/tag/2.17....
    • 바이너리 임베딩은 추가 재정렬이 필요하겠지만 테스트해보면 재미있을 듯함
      transformers.js v3의 npm 패키지를 만들어뒀고 업데이트해야 할 것 같음. 이 기능을 아직 포함했는지는 확실하지 않음
      주로 bun에서 돌아가게 하려고 포크를 유지했는데, v3가 릴리스되면 bun을 제대로 지원할 예정임. 다만 WebGPU는 동작하지 않겠지만 선택 기능임
      [편집: 쓰고 싶으면 DM 달라. 포크 홍보는 하고 싶지 않음]
  • 이 라이브러리로 gte-small(~0.07GB) 임베딩을 만들고 Upstash Vector에 저장하고 있음
    384차원뿐이지만 문단 단위 텍스트에서 놀랄 만큼 잘 동작함. 순위표에서도 text-embedding-ada-002보다 더 높게 나옴
    https://huggingface.co/spaces/mteb/leaderboard
  • Syntax 팟캐스트가 최근 Transformers.js와 개발자를 다룬 에피소드를 냈음
    https://syntax.fm/show/740/local-ai-models-in-javascript-mac...
  • transformers.js는 정말 멋진 라이브러리임
    BRIA AI의 RMBG1.4 모델로 이미지 배경 제거를 하는 작은 웹앱을 만들었음: https://aether.nco.dev
    데이터를 API로 보내지 않아도 되고 스마트폰에서도 돌아간다는 점이 아주 좋음. 앞으로 작은 비전, 언어, 기타 유틸리티 모델(깊이 추정, 배경 제거 등)에 이걸 쓰는 프로젝트가 많아질 것 같고 웹의 미래가 밝아 보임
    다음 프로젝트도 이미 작업 중이고, 거기서도 분명 transformers.js를 다시 쓸 예정임
    • 간단한 프로젝트에 쓰고 있음: https://github.com/sroussey/ellmers
      서버나 Electron 앱에서 쓸 여러 RAG 전략을 위해 임베딩과 검색 전략을 테스트하는 게 계획임
  • 정말 멋지지만, 아쉽게도 실용성은 꽤 낮아 보임. 모델은 대체로 꽤 크기 때문에 브라우저가 실행할 수 있더라도 브라우저까지 가져오는 과정에서 둘 중 하나가 필요함
    1. 웹사이트를 방문할 때마다 큰 다운로드
    2. 큰 모델을 쓰는 사이트마다 큰 다운로드와 높은 저장공간 사용량. 예를 들어 150개 사이트 × 800MB 모델이면 120GB 저장공간을 씀
      둘 다 별로임
      장기적으로는 브라우저가 일부 모델을 내장하고 표준화된 웹 API로 노출하는 방식이 맞을 수 있지만, 아직 그런 노력이 진행 중이라는 얘기는 못 들었음
    • 훨씬 작은 10~60MB 모델을 쓰는 데모를 많이 공개했음
      (44MB) 브라우저 내 배경 제거: https://huggingface.co/spaces/Xenova/remove-background-web. WebGPU 버전도 있음: https://huggingface.co/spaces/Xenova/remove-background-webgp...
      (51MB) 자동 음성 인식용 Whisper Web: https://huggingface.co/spaces/Xenova/whisper-web 설정에서 양자화 버전을 선택하면 됨
      (28MB) 단안 깊이 추정용 Depth Anything Web: https://huggingface.co/spaces/Xenova/depth-anything-web
      (14MB) 이미지 분할용 Segment Anything Web: https://huggingface.co/spaces/Xenova/segment-anything-web
      (20MB) 머신러닝 기반 스케치 인식 게임 Doodle Dash: https://huggingface.co/spaces/Xenova/doodle-dash
      그 외에도 훨씬 많음. 다른 예시는 Transformers.js 데모 컬렉션에서 볼 수 있음: https://huggingface.co/collections/Xenova/transformersjs-dem...
      모델은 도메인별로 캐시되며(Web Cache API 사용), 페이지를 로드할 때마다 다시 내려받을 필요는 없음. 도메인을 넘어 모델을 유지하고 싶다면 이 라이브러리로 브라우저 확장을 만들 수 있음
      마지막으로 말한 부분은 진행 중인 노력이 있지만 아직 이야기할 수 있는 단계는 아님
    • 10년 전 첫 Unreal/Unity asm.js 데모 이후 웹 게임을 괴롭혀온 문제와 거의 같고, 그동안 해결 쪽으로 별 진전이 없었음
      클라이언트에 기가바이트 단위 데이터를 필요로 하는 웹앱은 실용적으로 만들기 어려움. 사용자가 원하는 만큼 오래 캐시에 남아 있으리라고 보장할 안정적인 방법이 없고, 설령 안정적으로 캐시할 수 있어도 브라우저의 캐시 파티셔닝 정책 때문에 같은 모델을 쓰는 사이트마다 다운로드와 저장공간이 중복됨
    • 모델은 80MB 이하이고, 나머지는 LLM이라 범위 밖임. Whisper는 40MB, 임베딩은 23MB임
      원래 댓글의 “매우 비실용적으로 보임”, “모델은 대체로 꽤 큼”, “150개 사이트 × 800MB 모델” 같은 부분은 이해가 부족하다고 스스로 단서를 달고 있는 셈으로 보임
    • 일부 모델은 꽤 작아서 모든 데이터를 서버로 보내 처리하는 것보다 온디바이스로 돌릴 가치가 있음
      또 큰 장점은 transformers가 Node.js에서도 돌아간다는 점임. Python과 그 의존성의 이상한 조합을 맞추는 것보다 실행 환경을 만드는 게 훨씬 쉬움
    • 이건 브라우저만의 문제가 아니라 온디바이스 AI 처리의 본질적인 문제임
      운영체제가 모델을 미리 설치하고 브라우저 벤더도 쓸 수 있는 API를 제공하기 시작해야 나아질 것 같음
      그래도 대부분의 작업에서는 클라우드 호스팅 모델이 늘 훨씬 나을 가능성이 큼
  • 이제 Google 캡차에서 자전거나 다리를 모두 골라내는 브라우저 플러그인을 만들 수 있는 건가?
  • 학습은 불가능한가? 몇 년 전에 브라우저에서 작은 신경망을 만들고 학습시키는 작업을 해봤는데, 지금은 작은 커스텀 트랜스포머로 그런 방식이 더 잘 돌아갈지 궁금함
    • 이론적으로는 분명 가능하지만, 아마 성능 문제가 아직 구현되지 않은 이유일 것 같음
      Hugging Face Space에 WebGPU 임베딩 벤치마크가 있어서 순전파 동작을 가늠할 수 있음: https://huggingface.co/spaces/Xenova/webgpu-embedding-benchm...
      그 자체로는 인상적이지만, 그 지연시간으로 학습은 고통스러울 듯함. fp16, 배치 32, 시퀀스 길이 512에서 2,200만 매개변수 모델의 순전파가 약 500ms 걸림
  • 이러면 Node.js 서버리스 함수에서 이런 모델을 돌릴 가능성도 열리는 것 아닌가?
    온디맨드 예측에도 분명 가능성이 생길 듯함
  • Apple Silicon 가속을 지원하나?