llama.cpp 프로바이더

llama.cpp 프로바이더

lgrammel/ai-sdk-llama-cpp 는 네이티브 C++ 바인딩을 통해 Node.js 안에서 직접 llama.cpp로 로컬 LLM 추론을 가능하게 하는 커뮤니티 프로바이더예요.

이 프로바이더는 llama.cpp를 Node.js 메모리에 직접 로드해 외부 서버가 필요 없으면서도 네이티브 성능과 GPU 가속을 제공해요.

출처: 문서

본문

기능 (Features)

  • 네이티브 성능 (Native Performance): node-addon-api (N-API)를 사용한 직접 C++ 바인딩
  • GPU 가속 (GPU Acceleration): macOS에서 자동 Metal 지원
  • 스트리밍·비스트리밍 (Streaming & Non-streaming): generateText와 streamText 모두 완전 지원
  • 구조화 출력 (Structured Output): Output으로 스키마 검증과 함께 JSON 객체 생성
  • 임베딩 (Embeddings): embed와 embedMany로 임베딩 생성
  • 채팅 템플릿 (Chat Templates): 자동 또는 설정 가능한 채팅 템플릿 포맷팅 (llama3, chatml, gemma 등)
  • GGUF 지원 (GGUF Support): 어떤 GGUF 형식 모델이든 로드

참고: 이 프로바이더는 현재 macOS(Apple Silicon 또는 Intel)만 지원해요. Windows와 Linux는 지원되지 않아요.

사전 요구 사항 (Prerequisites)

설치 전에 다음을 확인하세요:

  • macOS (Apple Silicon 또는 Intel)
  • Node.js >= 22.0.0
  • CMake >= 3.15
  • Xcode Command Line Tools
# Xcode Command Line Tools 설치 (Clang 포함)
xcode-select --install

# Homebrew로 CMake 설치
brew install cmake

설정 (Setup)

llama.cpp 프로바이더는 ai-sdk-llama-cpp 모듈에서 사용할 수 있어요. 다음과 같이 설치할 수 있어요:

설치 시 llama.cpp를 Metal 지원 정적 라이브러리로 자동 컴파일하고 네이티브 Node.js 애드온을 빌드해요.

프로바이더 인스턴스 (Provider Instance)

ai-sdk-llama-cpp에서 llamaCpp를 임포트하고 모델 인스턴스를 만들 수 있어요:

import { llamaCpp } from 'ai-sdk-llama-cpp';

const model = llamaCpp({
  modelPath: './models/llama-3.2-1b-instruct.Q4_K_M.gguf',
});

설정 옵션 (Configuration Options)

다음 옵션으로 모델 인스턴스를 커스터마이즈할 수 있어요:

  • modelPath string (필수)

    GGUF 모델 파일 경로예요.

  • contextSize number

    최대 컨텍스트 크기. 기본값: 2048.

  • gpuLayers number

    GPU로 오프로드할 레이어 수. 기본값: 99 (전체 레이어). GPU를 비활성화하려면 0으로 설정하세요.

  • threads number

    CPU 스레드 수. 기본값: 4.

  • debug boolean

    llama.cpp의 상세 디버그 출력 활성화. 기본값: false.

  • chatTemplate string

    메시지 포맷팅에 사용할 채팅 템플릿. 기본값: "auto" (GGUF 모델 파일에 내장된 템플릿 사용). 사용 가능한 템플릿: llama3, chatml, gemma, mistral-v1, mistral-v3, phi3, phi4, deepseek 등.

const model = llamaCpp({
  modelPath: './models/your-model.gguf',
  contextSize: 4096,
  gpuLayers: 99,
  threads: 8,
  chatTemplate: 'llama3',
});

언어 모델 (Language Models)

텍스트 생성 (Text Generation)

llama.cpp 모델을 사용해 generateText 함수로 텍스트를 생성할 수 있어요:

import { generateText } from 'ai';
import { llamaCpp } from 'ai-sdk-llama-cpp';

const model = llamaCpp({
  modelPath: './models/llama-3.2-1b-instruct.Q4_K_M.gguf',
});

try {
  const { text } = await generateText({
    model,
    prompt: 'Explain quantum computing in simple terms.',
  });

  console.log(text);
} finally {
  await model.dispose();
}

스트리밍 (Streaming)

프로바이더는 streamText로 스트리밍을 완전 지원해요:

import { streamText } from 'ai';
import { llamaCpp } from 'ai-sdk-llama-cpp';

const model = llamaCpp({
  modelPath: './models/llama-3.2-1b-instruct.Q4_K_M.gguf',
});

try {
  const result = streamText({
    model,
    prompt: 'Write a haiku about programming.',
  });

  for await (const chunk of result.textStream) {
    process.stdout.write(chunk);
  }
} finally {
  await model.dispose();
}

구조화 출력 (Structured Output)

Output을 사용해 스키마를 준수하는 타입 안전한 JSON 객체를 생성해요:

import { generateText, Output } from 'ai';
import { z } from 'zod';
import { llamaCpp } from 'ai-sdk-llama-cpp';

const model = llamaCpp({
  modelPath: './models/your-model.gguf',
});

try {
  const { output: recipe } = await generateText({
    model,
    output: Output.object({
      schema: z.object({
        name: z.string(),
        ingredients: z.array(
          z.object({
            name: z.string(),
            amount: z.string(),
          }),
        ),
        steps: z.array(z.string()),
      }),
    }),
    prompt: 'Generate a recipe for chocolate chip cookies.',
  });

  console.log(recipe);
} finally {
  await model.dispose();
}

구조화 출력 기능은 GBNF 문법 제약을 사용해 모델이 스키마를 준수하는 유효한 JSON을 생성하도록 보장해요.

생성 파라미터 (Generation Parameters)

표준 AI SDK 생성 파라미터가 지원돼요:

const { text } = await generateText({
  model,
  prompt: 'Hello!',
  maxTokens: 256,
  temperature: 0.7,
  topP: 0.9,
  topK: 40,
  stopSequences: ['\n'],
});

임베딩 모델 (Embedding Models)

llamaCpp.embedding() 팩토리 메서드로 임베딩 모델을 만들 수 있어요:

import { embed, embedMany } from 'ai';
import { llamaCpp } from 'ai-sdk-llama-cpp';

const model = llamaCpp.embedding({
  modelPath: './models/nomic-embed-text-v1.5.Q4_K_M.gguf',
});

try {
  const { embedding } = await embed({
    model,
    value: 'Hello, world!',
  });

  const { embeddings } = await embedMany({
    model,
    values: ['Hello, world!', 'Goodbye, world!'],
  });
} finally {
  model.dispose();
}

모델 다운로드 (Model Downloads)

GGUF 형식 모델은 별도로 다운로드해야 해요. 인기 있는 출처:

다운로드 예시:

# models 디렉토리 생성
mkdir -p models

# 모델 다운로드 (예: Llama 3.2 1B)
wget -P models/ https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF/resolve/main/Llama-3.2-1B-Instruct-Q4_K_M.gguf

리소스 관리 (Resource Management)

경고: 작업이 끝나면 항상 model.dispose()를 호출해 모델을 언로드하고 GPU/CPU 리소스를 해제하세요. 특히 여러 모델을 로드할 때 메모리 누수를 방지하기 위해 중요해요.

const model = llamaCpp({
  modelPath: './models/your-model.gguf',
});

try {
  // 모델 사용...
} finally {
  await model.dispose();
}

제한 사항 (Limitations)

  • macOS 전용: Windows와 Linux는 지원되지 않아요
  • 도구/함수 호출 없음: 도구 호출은 지원되지 않아요
  • 이미지 입력 없음: 텍스트 프롬프트만 지원돼요

더 알아보기 (Learn more)

전체 사이트맵