소식
모델
API
keyboard_arrow_down
리더
URL을 읽거나 검색하면 대규모 모델에 대한 지원이 더 향상됩니다.
벡터 모델
세계적 수준의 다중 모드 다중 언어 임베딩.
재배열자
검색 관련성을 극대화하는 세계적 수준의 신경 검색기입니다.
MCP terminal명령줄articlellms.txtsmart_toy대리인data_object모델menu_book문서



로그인
login
기본 및 양자화된 GGUF
사용법 및 주의 사항
llama-embedding을 통한 효율적인 임베딩
벤치마크
결론
기술 블로그
8월 13, 2025

디코더 전용 벡터 모델용 GGUF 최적화

L4 GPU에서 30억 개의 파라미터를 가진 向量模型이 llama.cpp로 초당 4000 词元을 처리하는 속도는 아마도 최대한으로 빠른 속도일 것입니다. 정말 그럴까요?
Han Xiao
Han Xiao • 15 독서의 분

2주 전에 다양한 양자화 버전을 포함한 jina-embeddings-v4의 GGUF 형식을 출시했습니다. 이 모델은 멀티모달 다국어 검색을 위한 범용 向量模型입니다. 저희의 동기는 간단했습니다. 37.5억 개의 파라미터를 가진 모델인 jina-embeddings-v4의 바닐라 트랜스포머 버전은 저희의 GCP G2 (L4 GPU) API 인스턴스에서 잘 확장되지 않으므로 더 작고 빠른 GGUF 버전을 사용하여 추론 속도를 높이고 싶었습니다. 실험 중에 GGUF 向量模型을 변환하고 실행하면서 몇 가지 흥미로운 결과를 발견했습니다. llama.cpp 커뮤니티의 대부분이 대규모 언어 모델(LLM)에 집중하고 있기 때문에 向量模型 제공업체의 관점에서 이를 공유하는 것이 가치가 있다고 생각했습니다.

특히 주목할 점은 오늘날의 向量模型이 LLM과 거의 동일하다는 것입니다. 예를 들어 jina-embeddings-v4는 Qwen2.5-VL-3B-instruct를 기반으로 하고, jina-reranker-m0는 Qwen2-VL-2B를 기반으로 합니다. 유일한 실제 차이점은 출력입니다. LLM은 생성적이고, 向量模型과 重排器는 판별적입니다. 이는 기회와 과제를 동시에 만듭니다. 한편으로는 llama.cpp의 효율적인 구현(예: ubatch_size)을 활용하여 向量模型/重排器 모델을 제공할 수 있습니다. 다른 한편으로는 llama.cpp의 向量模型 구현은 대부분 RoBERTa 기반 모델과 같은 구형 인코더 전용 아키텍처를 위해 개발되었으며 최신 디코더 전용 向量模型/重排器 모델을 완전히 따라잡지 못했습니다. 이 기사에서는 최신 向量模型을 GGUF 형식 및 llama.cpp 도구(예: llama-embedding 및 llama-serving)와 함께 작동하도록 조정하면서 배운 내용을 공유합니다.

tag기본 및 양자화된 GGUF

jina-embeddings-v4는 세 개의 LoRA 어댑터(retrieval(검색 작업에 최적화됨), text-matching(문장 유사성 작업에 최적화됨) 및 code(코드 검색 작업에 최적화됨))와 함께 Qwen2.5-VL-3B-instruct를 기반으로 합니다. 또한 시각적 문서 검색 및 후기 상호 작용 스타일의 멀티 벡터 출력에 대해 집중적으로 학습되었습니다. 따라서 여기서의 아이디어는 Qwen2.5-VL-3B의 llama.cpp 기존 그래프 구현을 활용하고 추론을 위해 llama-embedding을 사용하는 것입니다.

그러나 가장 먼저 발견한 것은 llama.cpp의 mmproj 또는 비전 트랜스포머 구현의 버그였습니다. 이는 동일한 이미지 입력을 고려할 때 Qwen2.5-VL-3B의 torch 구현과 관련하여 다른 向量模型을 생성합니다. 저희 포크에서 이 문제를 해결하는 동안 GGUF 버전에서 비전 타워를 제외하기로 결정했습니다. 이 토론에 대한 자세한 내용은 여기에서 확인할 수 있습니다.

Multi-modal embeddings for jinaai/jina-embeddings-v4 · ggml-org llama.cpp · Discussion #14851
Hey folks! I’m working on getting multimodal embeddings working with jina-embeddings-v4 (based on Qwen 2.5 VL) through llama.cpp server. I’ve hit an issue with mtmd inconsistencies and was hoping s…
GitHubggml-org

멀티 벡터 向量模型 출력도 기본적으로 지원되지는 않지만 비전 트랜스포머만큼 큰 문제는 아닙니다. 멀티 벡터 출력은 마지막 트랜스포머 블록에서 학습된 MLP에서 제공되므로 최악의 경우 이 MLP를 numpy로 별도로 내보내고 llama.cpp에서 토큰 수준 向量模型을 가져온 후 적용할 수 있습니다. jina-reranker-m0-GGUF에 대해 수행한 작업입니다. 물론 그다지 효율적이지는 않지만 llama.cpp를 수정하고 다시 컴파일하지 않고도 작동합니다.

0:00
/0:04

비전 트랜스포머와 멀티 벡터 프로젝터를 제거하고 F16에서 세 개의 기본 GGUF 모델을 얻었습니다.

따라서 llama.cpp의 기존 Qwen2.5-VL-3B 그래프 구현을 완전히 준수하기 위해 비전 트랜스포머와 마지막 트랜스포머 블록의 멀티 벡터 프로젝터를 제거하고 모든 LoRA 어댑터를 기본 언어 모델에 다시 병합했습니다. 이를 통해 각 30.9억 개의 파라미터를 가진 세 개의 작업별 v4 모델을 얻었습니다. 이는 원래 v4의 37.5억 개 파라미터에서 줄어든 것입니다.

HuggingFace Repo Task
jinaai/jina-embeddings-v4-text-retrieval-GGUF Text retrieval
jinaai/jina-embeddings-v4-text-code-GGUF Code retrieval
jinaai/jina-embeddings-v4-text-matching-GGUF Sentence similarity

그런 다음 calibration_data_v5_rc.txt(여기에서 찾을 수 있고 여기에서 찾을 수 있고 Unsloth에서 권장함)를 사용하여 세 개의 기본 GGUF 모델을 보정하고 세 개의 imatrix 파일을 얻은 다음 llama-quantize와 imatrix를 사용하여 다음과 같이 float16에서 모델을 양자화했습니다.

# build imatrix
llama-imatrix -m jina-embeddings-v4-text-retrieval-F16.gguf -f calibration_data_v5_rc.txt -ngl 99 --no-ppl -o imatrix-retrieval-512.dat

# quantize
./quantize.sh jina-embeddings-v4-text-retrieval-F16.gguf retrieval-i3 imatrix-retrieval-512.dat jinaai/jina-embeddings-v4-text-retrieval-GGUF

quantize.sh 스크립트는 다음과 같습니다.

#!/bin/bash

F16_MODEL_FILE="$1"
OUTPUT_DIR="$2"
IMATRIX="$3"
HF_REPO="$4"

FILENAME="$(basename "$F16_MODEL_FILE")"
BASE_NAME="${FILENAME%-F16.gguf}"
BASE_NAME="${BASE_NAME%.gguf}"

mkdir -p "$OUTPUT_DIR"

# Array of quantization types
QUANT_TYPES=("IQ1_S" "IQ1_M" "IQ2_XXS" "IQ2_M" "Q2_K" "IQ4_NL" "IQ4_XS"  "IQ3_XXS" "IQ3_S" "IQ3_M" "IQ3_XS" "Q3_K_M" "Q4_K_M" "Q5_K_S" "Q5_K_M" "Q6_K" "Q8_0")

for quant_type in "${QUANT_TYPES[@]}"; do
    llama-quantize --imatrix "${IMATRIX}" "$F16_MODEL_FILE" "${OUTPUT_DIR}/${BASE_NAME}-${quant_type}.gguf" $quant_type 8
done

결국 모든 양자화 버전을 HuggingFace에 업로드했습니다.

양자화 BPW 파일 크기 (GB)
IQ1_S 2.04 0.73
IQ1_M 2.19 0.79
IQ2_XXS 2.44 0.88
IQ2_M 2.94 1.06
Q2_K 3.29 1.18
IQ3_XXS 3.31 1.19
IQ3_XS 3.59 1.29
IQ3_S 3.76 1.35
IQ3_M 3.84 1.38
Q3_K_M 4.11 1.48
IQ4_NL 4.72 1.69
IQ4_XS 4.49 1.61
Q4_K_M 4.99 1.79
Q5_K_S 5.61 2.02
Q5_K_M 5.75 2.07
Q6_K 6.56 2.36
Q8_0 8.50 3.05
F16 16.00 5.75
v3 (Transformers) 16.00 1.10
v4 (Transformers) 16.00 7.40

tag사용법 및 주의 사항

이제 llama-server 및 llama-embedding을 사용하여 임베딩을 위한 GGUF를 제공할 수 있습니다. 사용자 지정 입력 전처리 코드를 작성할 수 있는 유연성이 있는 트랜스포머 라이브러리와 달리, 이 부분을 수동으로 처리해야 합니다 (llama-server 및 llama-embedding을 다시 컴파일하지 않는 한). 특히 AutoModel.from_pretrained("jinaai/jina-embeddings-v4")...를 사용할 때와 완전히 일치하는 결과를 얻으려면 접두사에 대해 매우 신중해야 하며 GGUF 모델 입력에 수동으로 추가해야 합니다. 다음은 참조 표입니다.

작업 트랜스포머 구현의 prompt_name 모델에 대한 실제 입력
retrieval query (기본값) Query: {original_text}
retrieval passage Passage: {original_text}
text-matching query (기본값) Query: {original_text}
text-matching passage Query: {original_text} ⚠️
code query (기본값) Query: {original_text}
code passage Passage: {original_text}

일부 사용자는 prompt_name='passage'가 원래 AutoModel.from_pretrained("jinaai/jina-embeddings-v4")....에서 text-matching을 사용할 때 "Query: "로 재정의되는 것에 ⚠️ 놀랄 수 있습니다. 그러나 text-matching은 좌/우 역할이 없는 문장 유사성 작업이므로 입력은 대칭적입니다.

tagllama-server를 통해

llama.cpp를 설치한 후 llama-server를 실행하여 임베딩 모델을 OpenAI API 호환 HTTP 서버로 호스팅할 수 있습니다. 예를 들어 F16으로 text-matching을 사용하려면 다음을 수행할 수 있습니다.

llama-server -hf jinaai/jina-embeddings-v4-text-matching-GGUF:F16 --embedding --pooling mean -ub 8192

--pooling mean은 v4가 평균 풀링 임베딩이므로 필요합니다.

그런 다음 다음을 통해 요청을 보냅니다.

curl -X POST "http://127.0.0.1:8080/v1/embeddings" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [
      "Query: A beautiful sunset over the beach",
      "Query: Un beau coucher de soleil sur la plage",
      "Query: 海滩上美丽的日落",
      "Query: 浜辺に沈む美しい夕日"
    ]
  }'

retrieval 및 code 모델을 사용하는 경우 다음과 같이 입력 앞에 Query: 또는 Passage:를 추가합니다.

curl -X POST "http://127.0.0.1:8080/v1/embeddings" \
  -H "Content-Type: application/json" \
  -d '{
    "input": [
      "Query: A beautiful sunset over the beach",
      "Query: Un beau coucher de soleil sur la plage",
      "Passage: 海滩上美丽的日落",
      "Passage: 浜辺に沈む美しい夕日"
    ]
  }'

tagllama-embedding을 통해

빠른 건전성 검사를 위해 미리 컴파일된 llama-embedding을 사용하여 원샷 임베딩을 수행할 수도 있습니다. 다음 섹션에서 설명할 몇 가지 성능 문제가 있으므로 대량 임베딩에는 사용하지 않는 것이 좋습니다.

llama-embedding -hf jinaai/jina-embeddings-v4-text-matching-GGUF:F16 --pooling mean -p "Query: jina is awesome" --embd-output-format json  2>/dev/null

수정 및 개선 사항이 있는 llama-embedding 빌드를 사용하여 보다 효율적인 대량 임베딩에 대한 자세한 내용은 다음 섹션을 참조하십시오.

tag주의 사항 요약

보다 효율적인 구현으로 이동하기 전에 GGUF 모델의 주의 사항을 요약해 보겠습니다.

  • 텍스트 입력 앞에 Query: 또는 Passage: 를 수동으로 추가해야 합니다.
  • GGUF 모델에서 비전 트랜스포머를 제거했기 때문에 현재 이미지 입력을 처리할 수 없습니다. llama.cpp의 비전 트랜스포머/mmproj 구현의 버그 때문에 제거해야 했습니다. Qwen2.5-vl-3b를 수정하기 위해 업스트림과 협력하고 있습니다.
  • llama.cpp의 Qwen2.5-vl-3b 그래프 구현의 일부가 아니므로 다중 벡터 임베딩을 출력할 수 없습니다. llama.cpp를 다시 컴파일하지 않고 가장 쉬운 해결 방법은 llama-embedding에서 --pooling none을 설정하여 토큰 수준 임베딩을 가져온 후 MLP를 별도로 내보내고 실행하는 것입니다.
  • v4는 Matryoshka 표현 학습으로 학습되었으며 GGUF로 변환하면 이 기능이 유지됩니다. 모양이 NxD인 임베딩을 얻는 경우 embeddings[:, :truncate_dim]을 사용하여 더 작은 잘린 임베딩을 얻을 수 있습니다. 그러나 모든 차원이 학습되는 것은 아닙니다. v4의 경우 다음 특정 값에 대해 truncate_dim을 학습했습니다. [128, 256, 512, 1024, 2048]. 즉, embeddings[:, :131] 품질은 embeddings[:, :128] 및 embeddings[:, :256] 품질 사이의 일부 보간이 아니라 131차원이 학습되지 않았기 때문에 128차원 또는 256차원 임베딩보다 훨씬 나쁩니다.
  • 늦은 청크 분할은 --pooling none을 통해 토큰 수준 임베딩을 가져온 후 후처리 과정의 일부로 여전히 작동할 수 있습니다. llama.cpp 그래프에서 MLP를 분리한 것과 마찬가지로 그다지 효율적이지 않지만 다시 컴파일할 필요는 없습니다. 그러나 또 다른 주의 사항이 있습니다. v4는 인과 모델이므로 늦은 청크 분할은 더 이상 양방향이 아닙니다. 이전 청크 임베딩에는 후속 청크의 컨텍스트 정보가 포함되지 않습니다. v3에서는 트랜스포머 블록에서 양방향 주의 마스크를 사용했기 때문에 모든 청크 임베딩에 전역 컨텍스트 정보가 있었습니다. 내부적으로 인과성이 늦은 청크 분할을 쓸모없게 만드는지 여부를 논의했습니다. 일부는 "컨텍스트도 인과적이다"라고 주장합니다. 즉, 독자는 텍스트를 왼쪽에서 오른쪽으로 처리하므로 문장을 해석하는 데 필요한 컨텍스트는 이전 텍스트에서 가져와야 합니다. 다른 사람들은 늦은 청크 분할을 단방향 블록 컨텍스트 공유로 제한한다고 말합니다. 어느 쪽이든 v4에서 늦은 청크 분할의 효과는 여전히 의문스럽고 추가 연구가 필요합니다.

tagllama-embedding을 통한 효율적인 임베딩

llama-embedding은 매우 깔끔한 I/O (stdin, stdout)로 텍스트를 임베딩하기 위해 llama.cpp 위에 있는 비교적 간단한 C++ 래퍼입니다. 네트워크 대기열, 로드 밸런싱, 다중 테넌시 및 직렬화와 같은 다른 많은 문제가 있기 때문에 지금은 llama-server보다 개선하는 데 집중하고 있습니다. 저희의 질문은 간단합니다. L4 24GB GPU에서 얼마나 많은 속도를 얻을 수 있으며 긴 문서를 임베딩하는 데 필요한 최대 VRAM 사용량은 얼마입니까?

하지만 왜 L4일까요? 주로 GCP가 그 위에 매우 편리한 Cloud Run 기능을 제공하고 서버리스 추론 API에 사용할 수 있는 가장 널리 사용 가능하고 경제적인 GPU 유형이기 때문입니다. GCP는 요청 시 Cloud Run에서 A100 및 H100을 제공하며 더 나은 GPU를 사용하기 위해 GCP 팀에서 때때로 저희에게 제안을 합니다. 그러나 저희의 철학은 간단합니다. 3B 모델을 제공하기 위해 A100/H100이 필요한 경우 이는 분명히 저희의 기술 문제입니다.

몇 가지 배경 정보를 위해 llama.cpp에서 논리적 배치 크기 (-b)는 단일 평가 호출에서 모델에 제출되는 최대 토큰 수를 나타냅니다. 긴 입력을 처리할 때 이 크기까지 청크로 분할됩니다. 물리적 배치 크기(-ub)는 사용 가능한 메모리에 의해 제한되어 하드웨어를 통해 한 번의 순방향 패스에서 동시에 처리되는 실제 토큰 수입니다. KV 캐시는 각 물리적 배치가 완료된 후 업데이트됩니다. 컨텍스트 창(-c)은 모델이 한 번에 "볼" 수 있는 토큰 수에 대한 엄격한 제한입니다. v4 모델의 경우 이는 32,000개의 토큰이며 모델의 최대 주의 집중 범위를 나타냅니다. 전체 시퀀스에서 일관된 주의를 유지하려면 모든 토큰이 이 컨텍스트 창 내에 맞아야 합니다. 다음 그림은 이들의 관계를 보여줍니다.

tag수정 사항

GitHub - hanxiao/llama.cpp: C/C++의 LLM 추론
C/C++의 LLM 추론. GitHub에서 계정을 만들어 hanxiao/llama.cpp 개발에 참여하세요.
GitHubhanxiao

위의 포크에서 llama-embedding을 더욱 효율적으로 만들기 위해 몇 가지 최적화를 수행했습니다.

  • 단순화된 배치 처리: -b를 -c와 같게 자동으로 설정하여 이 매개변수를 사실상 쓸모없게 만들었습니다. 논리적 배치를 위해 모델의 전체 컨텍스트 길이를 항상 활용하므로 사용자는 더 이상 -b를 지정할 필요가 없습니다.
  • 유연한 메모리 제어: -ub가 -b와 같도록 강제되었던 원래 구현과는 달리(임베딩 모델이 인과적일 수 없다고 가정했기 때문에) 사용자가 -ub를 독립적으로 설정할 수 있도록 했습니다. 이를 통해 긴 컨텍스트를 인코딩할 때 최대 VRAM 사용량에 대한 세분화된 제어를 제공합니다. KV 캐시 구현 덕분에 VRAM 제한 내에 머물기 위해 작은 512 토큰 물리적 배치로 32K 컨텍스트를 처리할 수 있습니다. 이 변경 사항은 jina-embeddings-v4와 같은 인과적 임베딩 모델에만 올바릅니다. v3와 같은 인코더 전용 아키텍처의 경우 잘못된 구현입니다.
  • 수정된 평균 풀링: 원래 구현에서 이전에 깨졌던 ub < b인 경우 임베딩에 대한 평균 풀링 계산을 수정했습니다.

이 변경으로 인해 메모리 제약 조건을 효과적으로 관리하면서 긴 컨텍스트 디코더 전용 임베딩 모델을 훨씬 쉽게 사용할 수 있습니다. 이제 사용자는 다음 두 가지 매개변수만 구성하면 됩니다.

    • -c: 최대 컨텍스트 길이(임베딩 모델이 처리할 수 있는 토큰 수)
    • -ub: 물리적 배치 크기(GPU가 한 번에 처리하는 토큰 수)

따라서 L4에서 포크를 실행하기 위한 정확한 코드는 다음과 같습니다.

# Compile
git clone https://github.com/hanxiao/llama.cpp.git
cd llama.cpp
cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j 8

# Run
INPUT_PREFIX="Query: "  # or "Passage: "

cat big_input.txt | sed "s/^/${INPUT_PREFIX}/" | \
./llama.cpp/build/bin/llama-embedding -f /dev/stdin \
    -hf "jinaai/jina-embeddings-v4-text-retrieval-GGUF:FP16" \
    --pooling mean \
    --no-escape \
    --embd-output-format array \
    --ubatch-size 512 \
    --ctx-size 8192 \
    --flash-attn \
    -ngl 99 \
    > "embeddings.txt" 2> "error.log"

big_input.txt의 각 줄은 임베딩될 문장입니다.--no-escape는 문장 내 \n이 구분 기호로 해석되는 것을 방지하기 위해 설정해야 합니다. --flash-attn 및 -ngl 99는 L4 GPU에서 최상의 성능을 위해 설정해야 합니다.

tag벤치마크

벤치마킹을 통해 다음과 같은 질문을 이해하고 싶습니다.

  • 양자화가 원래 v4 Float16에 비해 얼마나 좋은가? v3 임베딩을 사용하는 것이 더 나을 정도로 성능이 저하되는 시점은 언제인가?
  • 각 양자화가 L4에서 얼마나 빨리 실행될 수 있으며 최대 VRAM 사용량은 얼마인가?
  • -ub 물리적 배치 크기 및 -c 컨텍스트 길이가 속도 및 최대 VRAM에 어떤 영향을 미치는가?

벤치마킹에 사용된 데이터 세트는 다음과 같습니다.

Task Documents Queries Relevant Pairs Avg Doc Length Max Doc Length Avg Query Length
NanoHotpotQA 5,090 50 100 57.3 345 14.9
NanoSciFact 2,919 50 56 205.8 1524 13.5
NanoArguAna 3,635 50 50 164.5 1058 193.0
NanoNFCorpus 2,953 50 2,518 223.3 1460 3.3
NanoFiQA2018 4,598 50 123 159.1 1882 10.2

벤치마킹을 위해 llama-embedding의 사용자 지정 빌드를 사용했습니다.

tag양자화 품질

가장 성능이 좋은 양자화 버전은 IQ3_M(3.84 BPW)입니다. 2비트 미만의 양자화는 v3보다 성능이 떨어지므로 사용하는 의미가 거의 없습니다.

Quantization NanoHotpotQA NanoFiQA2018 NanoArguAna NanoNFCorpus NanoSciFact
IQ1_S 0.6369 0.3178 0.3798 0.2933 0.5934
IQ1_M 0.6316 0.3313 0.5167 0.3256 0.6114
IQ2_XXS 0.7236 0.4582 0.4584 0.4067 0.7392
IQ2_M 0.7427 0.5869 0.5090 0.4468 0.7880
Q2_K 0.7683 0.5744 0.5168 0.4183 0.7546
IQ3_XXS 0.7780 0.5991 0.4811 0.4267 0.7610
IQ3_XS 0.7727 0.5615 0.5195 0.4439 0.7726
IQ3_S 0.8002 0.5505 0.4886 0.4381 0.7690
IQ3_M 0.8106 0.5387 0.5091 0.4462 0.7760
Q3_K_M 0.7567 0.5267 0.4486 0.4092 0.7775
IQ4_NL 0.7930 0.5598 0.4911 0.4285 0.7794
IQ4_XS 0.7979 0.5627 0.4947 0.4258 0.7789
Q4_K_M 0.8029 0.5569 0.4883 0.4226 0.7877
Q5_K_S 0.7969 0.5581 0.4721 0.4288 0.7842
Q5_K_M 0.7927 0.5601 0.4745 0.4247 0.7873
Q6_K 0.7951 0.5636 0.4822 0.4337 0.7846
Q8_0 0.7938 0.5687 0.4784 0.4335 0.7851
F16 0.7940 0.5610 0.4931 0.4343 0.7963
v3 (Transformers) 0.7393 0.5144 0.4600 0.4068 0.7820
v4 (Transformers) 0.7977 0.5571 0.4844 0.4351 0.7963

tag속도 및 VRAM

이제 벤치마크 데이터 세트를 NanoHotpotQA로 고정하고 모든 양자화를 가중치당 비트 수 대 속도(초당 토큰 수로 측정) 및 VRAM 소비량으로 플롯합니다. GGUF 버전이 FP16의 바닐라 버전보다 약간 더 빠릅니다(2023 대 1865 토큰/초). 대부분의 양자화는 2000-2100 토큰/초 주변에 클러스터링됩니다. 플래시 어텐션을 활성화하면 모든 양자화에서 약 77%의 속도 향상을 얻습니다(3000+ 대 2000+ 토큰/초). 그러나 초당 약 3700 토큰의 최고 성능을 보이는 양자화 Q8_0은 여전히 초당 16000 토큰을 기록하는 바닐라 v3(572M 파라미터)에 비해 훨씬 뒤쳐져 있습니다. 양자화된 버전은 상당한 VRAM을 절약하고 IQ3을 사용하여 v3 FP16 모델 수준에 거의 접근합니다.

Quantization BPW File Size (GB) Peak VRAM (GB) Token/s w FA Token/s w/o FA
IQ1_S 2.04 0.73 4.04 3625 2050
IQ1_M 2.19 0.79 4.09 3349 1997
IQ2_XXS 2.44 0.88 4.19 3701 2071
IQ2_M 2.94 1.06 4.37 3407 1989
Q2_K 3.29 1.18 4.49 3173 1905
IQ3_XXS 3.31 1.19 4.50 3668 2067
IQ3_XS 3.59 1.29 4.60 3604 2053
IQ3_S 3.76 1.35 4.66 3599 2049
IQ3_M 3.84 1.38 4.69 3603 2053
Q3_K_M 4.11 1.48 4.78 3450 2008
IQ4_NL 4.72 1.69 5.00 3571 2039
IQ4_XS 4.49 1.61 4.92 3585 2046
Q4_K_M 4.99 1.79 5.10 3558 2045
Q5_K_S 5.61 2.02 5.32 3567 2044
Q5_K_M 5.75 2.07 5.38 3528 2034
Q6_K 6.56 2.36 5.66 3334 1981
Q8_0 8.50 3.05 6.36 3767 2101
F16 16.00 5.75 9.70 3399 2023
v3 (Transformers) 16.00 1.10 2.82 16505
v4 (Transformers) 16.00 7.40 14.45 1865

시스템 정보 확장을 클릭하세요.

load_tensors: loading model tensors, this can take a while... (mmap = true)
load_tensors: offloading 36 repeating layers to GPU
load_tensors: offloading output layer to GPU
load_tensors: offloaded 37/37 layers to GPU
load_tensors: CUDA0 model buffer size = 3127.61 MiB
load_tensors: CPU_Mapped model buffer size = 315.30 MiB
...................................................................................
llama_context: constructing llama_context
llama_context: n_seq_max = 1
llama_context: n_ctx = 4096
llama_context: n_ctx_per_seq = 4096
llama_context: n_batch = 4096
llama_context: n_ubatch = 4096
llama_context: causal_attn = 1
llama_context: flash_attn = 1 // 1 for w/ FA in the table; 0 for w/o FA
llama_context: kv_unified = true
llama_context: freq_base = 1000000.0
llama_context: freq_scale = 1
llama_context: n_ctx_per_seq (4096) < n_ctx_train (128000) -- the full capacity of the model will not be utilized
llama_context: CUDA_Host output buffer size = 0.59 MiB
llama_kv_cache_unified: CUDA0 KV buffer size = 144.00 MiB
llama_kv_cache_unified: size = 144.00 MiB ( 4096 cells, 36 layers, 1/1 seqs), K (f16): 72.00 MiB, V (f16): 72.00 MiB
llama_context: CUDA0 compute buffer size = 2470.16 MiB
llama_context: CUDA_Host compute buffer size = 96.17 MiB
llama_context: graph nodes = 1234
llama_context: graph splits = 2
common_init_from_params: added <|endoftext|> logit bias = -inf
common_init_from_params: added <|im_end|> logit bias = -inf
common_init_from_params: added <|fim_pad|> logit bias = -inf
common_init_from_params: added <|repo_name|> logit bias = -inf
common_init_from_params: added <|file_sep|> logit bias = -inf
common_init_from_params: setting dry_penalty_last_n to ctx_size = 4096
common_init_from_params: warming up the model with an empty run - please wait ... (--no-warmup to disable)

system_info: n_threads = 4 (n_threads_batch = 4) / 8 | CUDA : ARCHS = 890 | USE_GRAPHS = 1 | PEER_MAX_BATCH_SIZE = 128 | CPU : SSE3 = 1 | SSSE3 = 1 | AVX = 1 | AVX2 = 1 | F16C = 1 | FMA = 1 | BMI2 = 1 | AVX512 = 1 | AVX512_VNNI = 1 | LLAMAFILE = 1 | OPENMP = 1 | REPACK = 1 |
main: n_tokens in batch = 0
main: number of embeddings = 5090

tag최적의 물리적 배치 및 컨텍스트 크기

이제 양자화 유형을 IQ3_S로 고정하고 물리적 배치 크기(-ub)와 컨텍스트 크기(-c)가 속도와 VRAM에 미치는 영향을 살펴봅니다. L4 GPU의 결과에 따르면 -ub=512, -c=2048이 최적의 구성이며, 2,025MB VRAM을 사용하면서 4,143 tokens/sec를 제공합니다. 여기서 알 수 있는 점은 입력에서 단일 문서의 최대 길이를 알고 있을 때 이를 커버할 만큼만 충분한 작은 컨텍스트 크기를 사용하는 것이 좋습니다. 물리적 배치 크기의 경우 512 토큰이 L4 GPU에서 가장 적합한 크기로 보입니다.

초당 토큰 성능

ubatch_size ctx_size=64 ctx_size=128 ctx_size=256 ctx_size=512
64 2233 2093 2128 2125
128 N/A 2866 2821 2877
256 N/A N/A 3287 3349
512 N/A N/A N/A 3469
ubatch_size ctx_size=2048 ctx_size=4096 ctx_size=8192 ctx_size=16384
256 3971 3630 3593 2766
512 4143 3797 3758 2852
1024 4059 3742 3707 2822
2048 3957 3631 3603 2762
4096 N/A 3450 3410 2625

최대 VRAM 사용량 (MB)

ubatch_size ctx_size=64 ctx_size=128 ctx_size=256 ctx_size=512
64 1691 1689 1689 1697
128 N/A 1729 1727 1737
256 N/A N/A 1803 1811
512 N/A N/A N/A 1963
ubatch_size ctx_size=2048 ctx_size=4096 ctx_size=8192 ctx_size=16384
256 1885 1947 2099 2409
512 2025 2101 2257 2577
1024 2329 2407 2571 2917
2048 2933 3025 3203 3597
4096 N/A 4285 4497 4985

tag결론

양자화된 GGUF를 예산 GPU에서 효율적으로 실행하려는 v4 사용자는 IQ3_S 또는 IQ3_M을 선택하고 llama-embedding의 사용자 지정 빌드를 사용하세요. 그러면 일반 데이터 세트(문장 길이가 2048 토큰 미만)에서 4000 토큰/초를 얻을 수 있습니다. 더 긴 문서를 포함하려면 컨텍스트 크기 -c를 늘리고 물리적 배치 크기 -ub를 제어하여 VRAM 사용량을 줄이세요. 사용자 지정 빌드를 사용하면 -ub를 1024와 같이 작은 숫자로 설정하여 3GB VRAM만 사용하여 매우 긴 문서(32K 토큰 이상)를 인코딩할 수 있습니다. 이는 원래 구현 또는 일반 트랜스포머에서는 불가능했던 작업입니다.

속도 최적화를 위한 노력은 결코 끝나지 않습니다. 항상 더 높은 처리량을 가진 더 빠르고 간결한 구현을 위한 여지가 있습니다. 4000 토큰/초가 우리의 한계는 아닐 것입니다. 해야 할 일이 훨씬 더 많습니다. llama.cpp에서 qwen2.5-vl-3b mmproj/vision 트랜스포머 구현을 수정하는 것 외에도 더 깊은 llama.graph 및 KV-캐시 수준 최적화, llama-serving 배치 로직 개선, 포함 API에 스트리밍 옵션 추가 등을 모색하고 있습니다. 우리의 목표는 llama.cpp가 현재 및 미래의 리랭커 릴리스를 위해 최신 디코더 전용 다중 모드 임베딩을 기본적으로 지원하도록 하는 것입니다.

범주:
기술 블로그
rss_feed

더 많은 뉴스
3월 11, 2026 • 7 독서의 분
멀티모달 LLM 을 활용한 오디오 임베딩 부트스트래핑
Han Xiao
Abstract illustration of a sound wave or heartbeat, formed by blue, orange, and gray dots on a white background.
3월 06, 2026 • 6 독서의 분
원시 수치 값에서 임베딩 모델 식별하기
Han Xiao
Fingerprint illustration made from numbers, showcasing digital and high-tech design on a light background.
9월 09, 2025 • 11 독서의 분
Llama.cpp 및 GGUF의 멀티모달 向量模型
Andrei Ungureanu
Alex C-G
Cartoon llama in the center of a white background, emitting laser-like beams from its eyes. The illustration creates a playfu
사무실
location_on
캘리포니아주 서니베일
710 Lakeway Dr, Ste 200, Sunnyvale, California 94085, United States
location_on
베를린, 독일
Prinzessinnenstraße 19-20, 10969 베를린, 독일
검색 기반
리더
벡터 모델
재배열자
Jina API 키 받기
비율 제한
API 상태
회사
회사 소개
영업팀에 문의
소식
인턴십 프로그램
지나 로고 다운로드
open_in_new
Elastic 로고 다운로드
open_in_new
자귀
안전
이용약관
은둔
쿠키 관리
email
탄력적인 지나 AI © 2020-2026.