WebLLM으로 로컬 및 오프라인 지원 챗봇 빌드

게시일: 2024년 1월 13일

이 도움말은 LLM 및 챗봇에 관한 3부 시리즈 중 두 번째입니다. 이전 도움말에서는 기기 내 및 브라우저 내 LLM의 이점과 단점을 설명했습니다.

이제 클라이언트 측 AI에 관해 자세히 알게 되었으므로 할 일 목록 웹 애플리케이션에 WebLLM을 추가할 수 있습니다. 코드는 GitHub 저장소의 web-llm 브랜치에서 찾을 수 있습니다.

WebLLM은 머신러닝 컴파일에서 제공하는 LLM용 웹 기반 런타임입니다. WebLLM을 독립형 애플리케이션으로 사용해 볼 수 있습니다. 이 애플리케이션은 Gemini와 같은 클라우드 지원 채팅 애플리케이션에서 영감을 얻었지만 LLM 추론은 클라우드 대신 기기에서 실행됩니다. 프롬프트와 데이터는 기기 외부로 전송되지 않으며 모델을 학습하는 데 사용되지 않습니다.

기기에서 모델 추론을 실행하기 위해 WebLLM은 WebAssemblyWebGPU를 결합합니다. WebAssembly는 중앙 처리 장치 (CPU)에서 효율적인 계산을 허용하지만 WebGPU는 개발자가 기기의 그래픽 처리 장치 (GPU)에 대한 로우레벨 액세스를 제공합니다.

Browser Support

  • Chrome: 113.
  • Edge: 113.
  • Firefox Technology Preview: supported.
  • Safari Technology Preview: supported.

Source

WebLLM 설치

WebLLM은 npm 패키지로 제공됩니다. npm install @mlc-ai/web-llm를 실행하여 이 패키지를 할 일 목록 애플리케이션에 추가할 수 있습니다.

모델 선택

다음으로 로컬에서 실행할 LLM을 결정해야 합니다. 다양한 모델을 사용할 수 있습니다.

결정하려면 다음과 같은 주요 용어와 수치를 알아야 합니다.

  • 토큰: LLM이 처리할 수 있는 가장 작은 텍스트 단위입니다.
  • 컨텍스트 윈도우: 모델이 처리할 수 있는 최대 토큰 수입니다.
  • 매개변수 또는 가중치: 학습 중에 학습된 내부 변수로, 수십억 개로 집계됩니다.
  • 양자화: 가중치를 나타내는 비트 수입니다. 비트 수가 많을수록 정밀도가 높아지지만 메모리 사용량도 늘어납니다.
  • 부동 소수점 수 형식: 32비트 부동 소수점 수 (전체 정밀도, F32)는 더 나은 정확성을 제공하는 반면, 16비트 부동 소수점 수 (절반 정밀도, F16)는 속도가 더 빠르고 메모리 사용량이 적지만 호환되는 하드웨어가 필요합니다.

이러한 주요 용어는 모델 이름의 일부가 되는 경향이 있습니다. 예를 들어 Llama-3.2-3B-Instruct-q4f32_1-MLC에는 다음 정보가 포함됩니다.

  • 모델은 LLaMa 3.2입니다.
  • 이 모델에는 30억 개의 매개변수가 있습니다.
  • 안내 및 프롬프트 스타일 어시스턴트 (Instruct)에 맞게 미세 조정됩니다.
  • 4비트 (q4) 균일 (_1) 양자화를 사용합니다.
  • 전체 정밀도 32비트 부동 소수점 숫자를 사용합니다.
  • 머신러닝 컴파일로 생성된 특수 버전입니다.

사용 사례에 적합한 모델을 결정하려면 여러 모델을 테스트해야 할 수도 있습니다.

이 글을 작성하는 시점에서 매개변수가 30억 개이고 매개변수당 4비트인 모델의 파일 크기는 이미 최대 1.4GB에 달할 수 있으며, 애플리케이션은 처음 사용하기 전에 사용자 기기에 다운로드해야 합니다. 3B 모델을 사용할 수도 있지만 번역 기능이나 잡지식 지식의 경우 7B 모델이 더 나은 결과를 제공합니다. 3.3GB 이상에서는 훨씬 더 큽니다.

WebLLM 엔진을 만들고 할 일 목록 챗봇의 모델 다운로드를 시작하려면 애플리케이션에 다음 코드를 추가합니다.

import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
  initProgressCallback: ({progress}) =>  console.log(progress);
});

CreateMLCEngine 메서드는 모델 문자열과 구성 객체(선택사항)를 사용합니다. initProgressCallback 메서드를 사용하여 모델의 다운로드 진행률을 쿼리하여 사용자가 기다리는 동안 이를 사용자에게 표시할 수 있습니다.

Cache API: LLM을 오프라인으로 실행

모델이 웹사이트의 캐시 저장소에 다운로드됩니다. Cache API는 웹사이트 또는 웹 애플리케이션을 오프라인으로 실행하기 위해 Service Worker와 함께 도입되었습니다. AI 모델을 캐시하는 데 가장 적합한 저장소 메커니즘입니다. HTTP 캐싱과 달리 Cache API는 개발자가 완전히 제어할 수 있는 프로그래매틱 캐시입니다.

다운로드되면 WebLLM은 네트워크를 통해 모델 파일을 요청하는 대신 Cache API에서 모델 파일을 읽으므로 WebLLM은 완전히 오프라인으로 작동할 수 있습니다.

모든 웹사이트 저장소와 마찬가지로 캐시는 출처별로 격리됩니다. 즉, 두 출처인 example.comexample.net은 동일한 스토리지를 공유할 수 없습니다. 두 웹사이트에서 동일한 모델을 사용하려면 모델을 별도로 다운로드해야 합니다.

애플리케이션 > 저장소로 이동하여 캐시 저장소를 열면 DevTools를 사용하여 캐시를 검사할 수 있습니다.

대화 설정

모델은 일련의 초기 프롬프트로 초기화할 수 있습니다. 일반적으로 메시지 역할에는 세 가지가 있습니다.

  • 시스템 프롬프트: 이 프롬프트는 모델의 동작, 역할, 캐릭터를 정의합니다. 또한 학습 세트의 일부가 아닌 커스텀 데이터 (예: 도메인별 데이터)를 모델에 제공하는 접지에도 사용할 수 있습니다. 시스템 프롬프트는 하나만 지정할 수 있습니다.
  • 사용자 프롬프트: 사용자가 입력한 프롬프트입니다.
  • 어시스턴트 프롬프트: 어시스턴트의 답변입니다(선택사항).

사용자 및 어시스턴트 프롬프트는 LLM이 어떻게 동작하거나 응답해야 하는지에 관한 자연어 예시를 LLM에 제공하여 N샷 프롬프트에 사용할 수 있습니다.

다음은 할 일 목록 앱의 대화를 설정하는 최소 예입니다.

const messages = [
  { role: "system",
    content: `You are a helpful assistant. You will answer questions related to
    the user's to-do list. Decline all other requests not related to the user's
    todos. This is the to-do list in JSON: ${JSON.stringify(todos)}`
  },
  {role: "user", content: "How many open todos do I have?"}
];

첫 번째 질문에 답변하기

채팅 완성 기능은 이전에 생성된 WebLLM 엔진 (engine.chat.completions)의 속성으로 노출됩니다. 모델이 다운로드된 후 이 속성에서 create() 메서드를 호출하여 모델 추론을 실행할 수 있습니다. 사용 사례의 경우 응답이 생성되는 동안 사용자가 읽기를 시작할 수 있도록 응답을 스트리밍하여 지각된 대기 시간을 줄여야 합니다.

const chunks = await engine.chat.completions.create({  messages,  stream: true, });

이 메서드는 숨겨진 AsyncIterator 클래스의 서브클래스인 AsyncGenerator를 반환합니다. for await...of 루프를 사용하여 청크가 들어올 때까지 기다립니다. 하지만 응답에는 새 토큰 (delta)만 포함되므로 전체 답장을 직접 조합해야 합니다.

let reply = '';

for await (const chunk of chunks) {
  reply += chunk.choices[0]?.delta.content ?? '';
  console.log(reply);
}

웹은 항상 스트리밍 응답을 처리해야 했습니다. DOMImplementation과 같은 API를 사용하여 이러한 스트리밍 응답을 처리하고 HTML을 효율적으로 업데이트할 수 있습니다.

결과는 순전히 문자열 기반입니다. JSON 또는 다른 파일 형식으로 해석하려면 먼저 파일을 파싱해야 합니다.

그러나 WebLLM에는 몇 가지 제한사항이 있습니다. 애플리케이션은 처음 사용하기 전에 대용량 모델을 다운로드해야 하며 이 모델은 출처 간에 공유할 수 없으므로 다른 웹 앱에서 동일한 모델을 다시 다운로드해야 할 수 있습니다. WebGPU는 거의 네이티브 수준의 추론 성능을 달성하지만 전체 네이티브 속도에는 도달하지 못합니다.

데모

이러한 단점은 Google에서 제안한 탐색 API인 Prompt API로 해결할 수 있습니다. 이 API는 클라이언트 측에서 실행되지만 Chrome에 다운로드된 중앙 모델을 사용합니다. 즉, 여러 애플리케이션에서 전체 실행 속도로 동일한 모델을 사용할 수 있습니다.

다음 도움말에서 Prompt API를 사용하여 챗봇 기능 추가에 관해 자세히 알아보세요.