llama.cpp dan GGUF Quantization: Deploy LLM Secara Lokal

# llama.cpp dan GGUF Quantization: Deploy LLM Secara Lokal ## Pendahuluan Menjalankan Large Language Model (LLM) secara lokal tanpa bergantung pada cloud API adalah impian banyak developer dan organ...

By Ruby Abdullah · · tutorial
llama.cppGGUFQuantizationLocal LLMPython

llama.cpp dan GGUF Quantization: Deploy LLM Secara Lokal

Pendahuluan

Menjalankan Large Language Model (LLM) secara lokal tanpa bergantung pada cloud API adalah impian banyak developer dan organisasi. Dengan llama.cpp, hal ini menjadi kenyataan. llama.cpp adalah framework inference LLM yang ditulis dalam C/C++ murni, dirancang untuk menjalankan model-model besar secara efisien di hardware consumer, termasuk laptop biasa.

Format GGUF (GPT-Generated Unified Format) adalah format model yang dioptimalkan untuk llama.cpp, mendukung berbagai level quantization yang memungkinkan Anda menukar antara kualitas model dan penggunaan memori sesuai kebutuhan hardware Anda.

Dalam tutorial ini, kita akan mempelajari cara menginstal llama.cpp, mendownload model GGUF dari HuggingFace, memahami level quantization, dan membangun chatbot lokal yang fully functional.

Prasyarat

  • Komputer dengan minimal 8GB RAM (16GB+ direkomendasikan)
  • Storage minimal 10GB free space
  • Python 3.8 atau lebih baru
  • Git dan CMake (untuk build dari source)
  • Opsional: GPU NVIDIA dengan CUDA atau Apple Silicon untuk akselerasi

Instalasi llama.cpp

Metode 1: Build dari Source (Direkomendasikan)

# Clone repository

git clone https://github.com/ggerganov/llama.cpp.git

cd llama.cpp

Build dasar (CPU only)

make

Atau menggunakan CMake

mkdir build && cd build

cmake ..

cmake --build . --config Release

Build dengan GPU Acceleration

# CUDA (NVIDIA GPU)

make GGMLCUDA=1

Atau via CMake

mkdir build && cd build

cmake .. -DGGMLCUDA=ON

cmake --build . --config Release

Metal (Apple Silicon / macOS)

make GGMLMETAL=1

Atau via CMake

mkdir build && cd build

cmake .. -DGGMLMETAL=ON

cmake --build . --config Release

Vulkan (cross-platform GPU)

make GGMLVULKAN=1

Metode 2: Instalasi via pip (Python Bindings)

# Instalasi dasar (CPU only)

pip install llama-cpp-python

Dengan CUDA support

CMAKEARGS="-DGGMLCUDA=on" pip install llama-cpp-python

Dengan Metal support (macOS)

CMAKEARGS="-DGGMLMETAL=on" pip install llama-cpp-python

Dengan Vulkan support

CMAKEARGS="-DGGMLVULKAN=on" pip install llama-cpp-python

Force reinstall jika upgrade

pip install llama-cpp-python --force-reinstall --no-cache-dir

Verifikasi Instalasi

# Untuk build dari source

./llama-cli --version

Untuk Python

python -c "from llamacpp import Llama; print('llama-cpp-python installed successfully')"

Memahami Format GGUF dan Level Quantization

Apa itu GGUF?

GGUF adalah format file yang dirancang khusus untuk menyimpan model LLM yang telah di-quantize. Format ini menggantikan format GGML sebelumnya dan menawarkan:

  • Backward dan forward compatibility yang lebih baik
  • Metadata yang lebih lengkap (tokenizer info, parameter model, dll)
  • Loading yang lebih cepat
  • Dukungan untuk berbagai arsitektur model

Level Quantization

Quantization adalah proses mengurangi presisi numerik dari parameter model untuk menghemat memori dan meningkatkan kecepatan, dengan trade-off pada kualitas output.

| Quantization | Bits | Ukuran Model (7B) | RAM Needed | Kualitas | Use Case |

|-------------|------|-------------------|------------|----------|----------|

| F16 | 16 | ~14 GB | ~16 GB | Terbaik | Referensi, evaluasi |

| Q80 | 8 | ~7.5 GB | ~10 GB | Sangat Baik | Produksi (jika RAM cukup) |

| Q6K | 6 | ~5.5 GB | ~8 GB | Baik Sekali | Balance kualitas/performa |

| Q5KM | 5 | ~5.0 GB | ~7.5 GB | Baik | Rekomendasi umum |

| Q5KS | 5 | ~4.8 GB | ~7 GB | Baik | Sedikit lebih kecil |

| Q4KM | 4 | ~4.0 GB | ~6.5 GB | Cukup Baik | Paling populer |

| Q4KS | 4 | ~3.8 GB | ~6 GB | Cukup | RAM terbatas |

| Q3KM | 3 | ~3.3 GB | ~5.5 GB | Menurun | Hanya jika RAM sangat terbatas |

| Q2K | 2 | ~2.7 GB | ~5 GB | Rendah | Eksperimen saja |

Rekomendasi:
  • Q4KM: Best balance antara ukuran dan kualitas (paling populer)
  • Q5KM: Untuk kualitas lebih baik dengan sedikit tambahan RAM
  • Q80: Jika RAM bukan masalah, kualitas mendekati F16

Naming Convention GGUF

model-name-{size}-{type}.{quantization}.gguf

Contoh:

  • Meta-Llama-3-8B-Instruct-Q4KM.gguf
  • mistral-7b-instruct-v0.3-Q5KM.gguf
  • phi-3-mini-4k-instruct-Q80.gguf

Download Model GGUF dari HuggingFace

Menggunakan huggingface-cli

# Install huggingfacehub

pip install huggingfacehub

Download model spesifik

huggingface-cli download \

TheBloke/Llama-2-7B-Chat-GGUF \

llama-2-7b-chat.Q4KM.gguf \

--local-dir ./models

Download dari bartowski (source GGUF populer)

huggingface-cli download \

bartowski/Meta-Llama-3.1-8B-Instruct-GGUF \

Meta-Llama-3.1-8B-Instruct-Q4KM.gguf \

--local-dir ./models

Menggunakan Python

from huggingfacehub import hfhubdownload

Download model

modelpath = hfhubdownload(

repoid="bartowski/Meta-Llama-3.1-8B-Instruct-GGUF",

filename="Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

localdir="./models"

)

print(f"Model downloaded to: {modelpath}")

Model Populer yang Direkomendasikan

# Llama 3.1 8B (Meta, general purpose)

huggingface-cli download bartowski/Meta-Llama-3.1-8B-Instruct-GGUF \

Meta-Llama-3.1-8B-Instruct-Q4KM.gguf --local-dir ./models

Mistral 7B (Mistral AI, efficient)

huggingface-cli download TheBloke/Mistral-7B-Instruct-v0.2-GGUF \

mistral-7b-instruct-v0.2.Q4KM.gguf --local-dir ./models

Phi-3 Mini (Microsoft, compact)

huggingface-cli download bartowski/Phi-3.5-mini-instruct-GGUF \

Phi-3.5-mini-instruct-Q4KM.gguf --local-dir ./models

Qwen2 7B (Alibaba, multilingual)

huggingface-cli download Qwen/Qwen2-7B-Instruct-GGUF \

qwen2-7b-instruct-q4km.gguf --local-dir ./models

Penggunaan CLI llama.cpp

Inference Dasar

# Text completion

./llama-cli -m ./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf \

-p "Jelaskan apa itu machine learning dalam 3 kalimat:" \

-n 256 \

--temp 0.7

Interactive chat mode

./llama-cli -m ./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf \

--interactive \

--color \

-n -1 \

--temp 0.7 \

--top-p 0.9 \

--repeat-penalty 1.1

Parameter Penting CLI

./llama-cli -m model.gguf \

-p "prompt text" \

-n 512 # Max tokens to generate

--temp 0.7 # Temperature (0.0 = deterministic, 1.0 = creative)

--top-p 0.9 # Top-p sampling

--top-k 40 # Top-k sampling

--repeat-penalty 1.1 # Penalti pengulangan

-c 4096 # Context length

-t 8 # Jumlah CPU threads

-ngl 35 # Jumlah layer di GPU (untuk GPU offloading)

--seed 42 # Random seed untuk reproducibility

GPU Offloading

# Offload semua layer ke GPU

./llama-cli -m model.gguf -ngl 999 -p "Hello"

Offload sebagian layer ke GPU (untuk GPU dengan VRAM terbatas)

./llama-cli -m model.gguf -ngl 20 -p "Hello"

Cek berapa layer model

./llama-cli -m model.gguf --verbose-prompt -p "test" -n 1

Python Bindings: llama-cpp-python

Penggunaan Dasar

from llamacpp import Llama

Load model

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=4096, # Context window

nthreads=8, # CPU threads

ngpulayers=35, # GPU layers (0 untuk CPU only)

verbose=False

)

Text completion

output = llm(

"Jelaskan apa itu neural network:",

maxtokens=256,

temperature=0.7,

topp=0.9,

stop=["###", "\n\n\n"]

)

print(output["choices"][0]["text"])

Chat Completion (Format OpenAI-Compatible)

from llamacpp import Llama

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=4096,

ngpulayers=-1, # -1 = semua layer ke GPU

chatformat="llama-3" # Format chat sesuai model

)

Single turn

response = llm.createchatcompletion(

messages=[

{"role": "system", "content": "Kamu adalah asisten AI yang membantu."},

{"role": "user", "content": "Apa keuntungan menjalankan LLM secara lokal?"}

],

maxtokens=512,

temperature=0.7

)

print(response["choices"][0]["message"]["content"])

Streaming Response

from llamacpp import Llama

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=4096,

ngpulayers=-1

)

Streaming output

stream = llm.createchatcompletion(

messages=[

{"role": "system", "content": "Kamu adalah asisten AI."},

{"role": "user", "content": "Tulis puisi pendek tentang programming"}

],

maxtokens=256,

stream=True

)

for chunk in stream:

delta = chunk["choices"][0]["delta"]

if "content" in delta:

print(delta["content"], end="", flush=True)

print() # Newline di akhir

Multi-turn Conversation

from llamacpp import Llama

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=4096,

ngpulayers=-1

)

Simpan history percakapan

conversationhistory = [

{"role": "system", "content": "Kamu adalah asisten AI yang ahli dalam Python programming."}

]

def chat(usermessage):

conversationhistory.append({"role": "user", "content": usermessage})

response = llm.createchatcompletion(

messages=conversationhistory,

maxtokens=512,

temperature=0.7

)

assistantmessage = response["choices"][0]["message"]["content"]

conversationhistory.append({"role": "assistant", "content": assistantmessage})

return assistantmessage

Percakapan multi-turn

print(chat("Apa itu list comprehension di Python?"))

print(chat("Berikan 3 contoh penggunaannya"))

print(chat("Bagaimana performanya dibanding for loop biasa?"))

OpenAI-Compatible Server

llama.cpp menyediakan server yang kompatibel dengan OpenAI API, sehingga Anda bisa menggunakan model lokal sebagai drop-in replacement untuk OpenAI.

Menjalankan Server

# Dari build source

./llama-server \

-m ./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf \

--host 0.0.0.0 \

--port 8080 \

-c 4096 \

-ngl 35 \

--embedding

Atau via Python

python -m llamacpp.server \

--model ./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf \

--host 0.0.0.0 \

--port 8080 \

--nctx 4096 \

--ngpulayers 35

Menggunakan dengan OpenAI Python SDK

from openai import OpenAI

Point ke server lokal

client = OpenAI(

baseurl="http://localhost:8080/v1",

apikey="not-needed" # API key tidak diperlukan untuk server lokal

)

Chat completion (sama persis dengan OpenAI API)

response = client.chat.completions.create(

model="local-model",

messages=[

{"role": "system", "content": "You are a helpful assistant."},

{"role": "user", "content": "Explain quantum computing in simple terms"}

],

maxtokens=512,

temperature=0.7

)

print(response.choices[0].message.content)

Streaming

stream = client.chat.completions.create(

model="local-model",

messages=[

{"role": "user", "content": "Write a Python function to sort a list"}

],

stream=True

)

for chunk in stream:

if chunk.choices[0].delta.content:

print(chunk.choices[0].delta.content, end="")

Menggunakan dengan curl

# Chat completion

curl http://localhost:8080/v1/chat/completions \

-H "Content-Type: application/json" \

-d '{

"messages": [

{"role": "system", "content": "You are a helpful assistant."},

{"role": "user", "content": "Hello!"}

],

"maxtokens": 256,

"temperature": 0.7

}'

Text embedding

curl http://localhost:8080/v1/embeddings \

-H "Content-Type: application/json" \

-d '{

"input": "Machine learning is fascinating",

"model": "local-model"

}'

Kebutuhan Memori dan Performance Benchmarks

Estimasi Kebutuhan RAM

Formula: RAM = (Model Size in GB) + (Context Length  0.5MB per 1K tokens) + 1GB overhead

Contoh untuk Llama 3.1 8B Q4KM:

  • Model size: ~4.5 GB
  • Context 4096 tokens: ~2 GB
  • Overhead: ~1 GB
  • Total: ~7.5 GB RAM

Contoh untuk Llama 3.1 70B Q4KM:

  • Model size: ~40 GB
  • Context 4096 tokens: ~4 GB
  • Overhead: ~2 GB
  • Total: ~46 GB RAM

Benchmark Performa (Approximate)

| Hardware | Model | Quantization | Speed (tokens/s) |

|----------|-------|-------------|------------------|

| M2 MacBook Air | Llama 3 8B | Q4KM | ~30-40 |

| M2 Pro | Llama 3 8B | Q4KM | ~45-55 |

| RTX 3060 12GB | Llama 3 8B | Q4KM | ~50-70 |

| RTX 4090 | Llama 3 8B | Q4KM | ~100-130 |

| CPU (i7-12700) | Llama 3 8B | Q4KM | ~8-15 |

| RTX 4090 | Llama 3 70B | Q4KM | ~15-25 |

Mengukur Performa

import time

from llamacpp import Llama

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=2048,

ngpulayers=-1,

verbose=True # Akan menampilkan statistik performa

)

Benchmark

prompt = "Explain the theory of relativity in detail:"

starttime = time.time()

output = llm(prompt, maxtokens=256)

elapsed = time.time() - starttime

tokensgenerated = output["usage"]["completiontokens"]

tokenspersecond = tokensgenerated / elapsed

print(f"Tokens generated: {tokensgenerated}")

print(f"Time elapsed: {elapsed:.2f}s")

print(f"Speed: {tokenspersecond:.1f} tokens/s")

Contoh Praktis: Membangun Chatbot Lokal

Mari kita bangun chatbot interaktif yang berjalan sepenuhnya di mesin lokal.

import sys

from llamacpp import Llama

class LocalChatbot:

def init(self, modelpath, systemprompt=None):

print("Loading model... (this may take a moment)")

self.llm = Llama(

modelpath=modelpath,

nctx=4096,

ngpulayers=-1,

verbose=False

)

self.systemprompt = systemprompt or (

"Kamu adalah asisten AI yang cerdas dan membantu. "

"Jawab dalam bahasa yang sama dengan pertanyaan user. "

"Berikan jawaban yang informatif namun ringkas."

)

self.conversation = [

{"role": "system", "content": self.systemprompt}

]

print("Model loaded. Ready to chat!\n")

def chat(self, userinput):

self.conversation.append({"role": "user", "content": userinput})

response = self.llm.createchatcompletion(

messages=self.conversation,

maxtokens=1024,

temperature=0.7,

topp=0.9,

repeatpenalty=1.1,

stream=True

)

fullresponse = ""

for chunk in response:

delta = chunk["choices"][0]["delta"]

if "content" in delta:

token = delta["content"]

print(token, end="", flush=True)

fullresponse += token

print() # Newline

self.conversation.append({"role": "assistant", "content": fullresponse})

# Trim conversation jika terlalu panjang

if len(self.conversation) > 20:

self.conversation = [self.conversation[0]] + self.conversation[-10:]

return fullresponse

def reset(self):

self.conversation = [

{"role": "system", "content": self.systemprompt}

]

print("Conversation reset.\n")

def run(self):

print("=" 50)

print("LOCAL AI CHATBOT")

print("=" 50)

print("Commands: /reset (reset conversation), /quit (exit)")

print("=" 50)

while True:

try:

userinput = input("\nYou: ").strip()

if not userinput:

continue

if userinput.lower() == "/quit":

print("Goodbye!")

break

if userinput.lower() == "/reset":

self.reset()

continue

print("\nAI: ", end="")

self.chat(userinput)

except KeyboardInterrupt:

print("\n\nGoodbye!")

break

Jalankan chatbot

if name == "main":

bot = LocalChatbot(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

systemprompt=(

"Kamu adalah asisten AI untuk perusahaan teknologi. "

"Bantu user dengan pertanyaan tentang programming, "

"data science, dan teknologi secara umum. "

"Jawab dengan bahasa yang mudah dipahami."

)

)

bot.run()

Chatbot dengan FastAPI Web Interface

from fastapi import FastAPI, HTTPException

from fastapi.middleware.cors import CORSMiddleware

from pydantic import BaseModel

from llamacpp import Llama

from fastapi.responses import StreamingResponse

import json

app = FastAPI(title="Local LLM Chatbot API")

app.addmiddleware(

CORSMiddleware,

alloworigins=[""],

allowmethods=[""],

allowheaders=["*"],

)

Load model saat startup

llm = Llama(

modelpath="./models/Meta-Llama-3.1-8B-Instruct-Q4KM.gguf",

nctx=4096,

ngpulayers=-1,

verbose=False

)

class ChatRequest(BaseModel):

messages: list

maxtokens: int = 512

temperature: float = 0.7

stream: bool = False

@app.post("/v1/chat")

async def chat(request: ChatRequest):

if request.stream:

return StreamingResponse(

streamresponse(request),

mediatype="text/event-stream"

)

response = llm.createchatcompletion(

messages=request.messages,

maxtokens=request.maxtokens,

temperature=request.temperature

)

return {

"response": response["choices"][0]["message"]["content"],

"usage": response["usage"]

}

async def streamresponse(request):

stream = llm.createchatcompletion(

messages=request.messages,

maxtokens=request.maxtokens,

temperature=request.temperature,

stream=True

)

for chunk in stream:

delta = chunk["choices"][0]["delta"]

if "content" in delta:

data = json.dumps({"content": delta["content"]})

yield f"data: {data}\n\n"

yield "data: [DONE]\n\n"

@app.get("/health")

async def health():

return {"status": "ok", "model": "loaded"}

Jalankan dengan: uvicorn chatbotapi:app --host 0.0.0.0 --port 8000

Tips Optimasi dan Troubleshooting

Optimasi Performa

# 1. Gunakan jumlah thread yang tepat (biasanya = jumlah performance cores)

./llama-cli -m model.gguf -t 8 -p "test"

2. Sesuaikan context length (lebih kecil = lebih cepat)

./llama-cli -m model.gguf -c 2048 -p "test"

3. Gunakan batch size yang optimal

./llama-cli -m model.gguf -b 512 -p "test"

4. Enable memory mapping (default on)

./llama-cli -m model.gguf --mmap -p "test"

Troubleshooting Umum

# Error: "not enough memory"

Solusi: Gunakan quantization lebih rendah atau kurangi context length

llm = Llama(

modelpath="model-Q4KM.gguf", # Gunakan Q4 bukan Q8

nctx=2048, # Kurangi context

ngpulayers=0 # CPU only jika GPU VRAM penuh

)

Error: "CUDA out of memory"

Solusi: Offload sebagian layer saja ke GPU

llm = Llama(

modelpath="model.gguf",

ngpulayers=20 # Bukan -1 (semua), tapi sebagian saja

)

Error: "model file not found"

Solusi: Gunakan absolute path

import os

modelpath = os.path.abspath("./models/model.gguf")

llm = Llama(modelpath=modelpath)

Slow performance di CPU

Solusi: Compile ulang dengan optimasi AVX2/AVX512

make clean && make LLAMAAVX2=1

Kesimpulan

llama.cpp dan format GGUF telah merevolusi cara kita menjalankan LLM secara lokal. Dengan quantization yang tepat, Anda bisa menjalankan model-model canggih bahkan di laptop biasa tanpa GPU dedicated.

Poin-poin penting yang perlu diingat:

  • Pilih quantization yang tepat: Q4KM untuk balance terbaik, Q5KM untuk kualitas lebih, Q80 jika RAM cukup
  • Manfaatkan GPU: Offloading ke GPU memberikan peningkatan performa yang signifikan
  • Gunakan OpenAI-compatible server: Memudahkan integrasi dengan aplikasi yang sudah ada
  • Sesuaikan context length: Semakin kecil context, semakin cepat dan hemat memori
  • Python bindings: llama-cpp-python membuat integrasi ke aplikasi Python sangat mudah
  • Perhatikan kebutuhan RAM: Pastikan hardware Anda sesuai dengan model yang dipilih

Dengan menguasai llama.cpp, Anda memiliki kemampuan untuk menjalankan AI yang powerful secara privat, tanpa biaya API, dan tanpa batasan rate limit.

Referensi

  • Repository llama.cpp: https://github.com/ggerganov/llama.cpp
  • llama-cpp-python: https://github.com/abetlen/llama-cpp-python
  • HuggingFace GGUF Models: https://huggingface.co/models?library=gguf
  • GGUF Specification: https://github.com/ggerganov/ggml/blob/master/docs/gguf.md

Artikel Terkait

PaddleOCR: Ekstraksi Teks dari Gambar dan Dokumen dengan Akurasi Tinggi

PaddleOCR: Ekstraksi Teks dari Gambar dan Dokumen dengan Akurasi Tinggi Halo temen-temen, kali ini kita bahas salah satu...

OpenVINO: Menjalankan Model AI dengan Cepat di CPU, iGPU, dan NPU Intel

OpenVINO: Menjalankan Model AI dengan Cepat di CPU, iGPU, dan NPU Intel Halo temen-temen, di tutorial kali ini aku mau n...

TensorRT-LLM: Memeras Throughput Maksimal dari GPU NVIDIA untuk Inference LLM

TensorRT-LLM: Memeras Throughput Maksimal dari GPU NVIDIA untuk Inference LLM Halo temen-temen, kali ini kita bahas sala...

DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi

DSPy: Berhenti Ngoprek Prompt Manual, Biarkan Compiler yang Optimasi Halo temen-temen, kali ini aku mau ngenalin satu li...