GGUF Format Model Yükleme: LocalAI Konfigürasyonu

LocalAI kurulumunu tamamladınız, modellerinizi indirdiniz ama sistem hala “model not found” hatası veriyor. Tanıdık geldi mi? GGUF formatındaki modelleri LocalAI’ye tanıtmak, sadece dosyayı bir klasöre atmaktan ibaret değil. Doğru konfigürasyon olmadan en iyi model bile işe yaramıyor. Bu yazıda GGUF modellerini LocalAI’de düzgün çalıştırmak için gereken her şeyi, gerçek sunucu senaryolarıyla birlikte ele alacağız.

GGUF Nedir ve Neden Önemli?

GGUF (GPT-Generated Unified Format), llama.cpp ekosisteminin geliştirdiği ve GGML formatının yerini alan model depolama formatıdır. 2023 ortasından itibaren neredeyse tüm quantize edilmiş modeller bu formatta dağıtılıyor.

GGUF’un sysadmin açısından güzel yanları şunlar:

  • Tek dosya: Model ağırlıkları, tokenizer, metadata hepsi tek .gguf dosyasında
  • Quantization seçenekleri: Q4_K_M, Q5_K_M, Q8_0 gibi farklı boyut/kalite dengesi
  • CPU ve GPU desteği: Aynı model dosyasıyla hem CPU hem CUDA/Metal çalışıyor
  • Hızlı yükleme: Memory-mapped dosya okuma desteği

LocalAI arka planda llama.cpp kullandığı için GGUF desteği native olarak geliyor. Ancak her modelin kendi konfigürasyon dosyasına ihtiyacı var.

Ortam Hazırlığı

Önce LocalAI’nin çalıştığını ve model dizininin doğru mount edildiğini kontrol edelim. Docker ile çalışıyorsanız şu yapıyı kullanıyor olmalısınız:

# LocalAI dizin yapısını oluştur
mkdir -p /opt/localai/{models,config}

# Docker Compose ile başlatma
cat > /opt/localai/docker-compose.yml << 'EOF'
version: '3.8'
services:
  localai:
    image: quay.io/go-skynet/local-ai:latest
    ports:
      - "8080:8080"
    volumes:
      - /opt/localai/models:/models
      - /opt/localai/config:/config
    environment:
      - MODELS_PATH=/models
      - CONFIG_FILE=/config
      - THREADS=4
      - CONTEXT_SIZE=2048
    restart: unless-stopped
EOF

docker compose -f /opt/localai/docker-compose.yml up -d

GPU’nuz varsa CUDA desteği için image tag’ini değiştirin:

# CUDA destekli image
image: quay.io/go-skynet/local-ai:latest-gpu-nvidia-cuda-12

# docker-compose.yml'e eklenecek GPU konfigürasyonu
deploy:
  resources:
    reservations:
      devices:
        - driver: nvidia
          count: all
          capabilities: [gpu]

Model İndirme ve Doğrulama

Hugging Face’den model indirirken hangi quantization’ı seçeceğiniz sunucunuzun RAM/VRAM kapasitesine göre değişir:

  • Q4_K_M: Düşük bellek kullanımı, kabul edilebilir kalite (üretim için popüler tercih)
  • Q5_K_M: Orta bellek, daha iyi kalite
  • Q8_0: Yüksek bellek, originale yakın kalite
  • F16: Tam precision, çok yüksek bellek (genellikle GPU gerekli)
# wget ile model indirme
cd /opt/localai/models

wget -c https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/main/llama-2-7b-chat.Q4_K_M.gguf 
  -O llama-2-7b-chat.Q4_K_M.gguf

# SHA256 doğrulama (Hugging Face model sayfasındaki hash ile karşılaştırın)
sha256sum llama-2-7b-chat.Q4_K_M.gguf

# Dosya boyutunu ve formatını kontrol et
ls -lh llama-2-7b-chat.Q4_K_M.gguf
file llama-2-7b-chat.Q4_K_M.gguf

İndirme tamamlandığında dosya tipini kontrol edin. Gerçek bir GGUF dosyası data olarak görünür, bozuk veya yarım inmiş dosyalar farklı çıktı verir.

YAML Konfigürasyon Dosyası Oluşturma

İşin kritik kısmı burası. LocalAI her model için ayrı bir YAML konfigürasyon dosyası bekliyor. Bu dosya olmadan model hiç yüklenmez.

# Temel konfigürasyon dosyası oluştur
cat > /opt/localai/models/llama-2-7b-chat.yaml << 'EOF'
name: llama-2-7b-chat
backend: llama
parameters:
  model: llama-2-7b-chat.Q4_K_M.gguf
  context_size: 2048
  threads: 4
  temperature: 0.7
  top_p: 0.95
  top_k: 40
  repeat_penalty: 1.1

template:
  chat: |
    [INST] <<SYS>>
    You are a helpful assistant.
    <</SYS>>
    {{.Input}} [/INST]

system_prompt: "You are a helpful, honest assistant."
EOF

Bu temel yapı çoğu Llama-2 türevi model için çalışır. Parametrelerin ne işe yaradığını açıklayalım:

name: API’ye gönderirken kullanacağınız model adı. OpenAI uyumlu endpoint’lerde model parametresine bu ismi yazacaksınız.

backend: Kullanılacak inference backend. GGUF için her zaman llama kullanın.

model: /models dizinine göre relatif dosya yolu.

context_size: Token bazında maksimum bağlam penceresi. RAM ile doğrudan ilişkili, büyük değerler daha fazla bellek ister.

threads: CPU thread sayısı. Genellikle fiziksel çekirdek sayısının yarısından başlayıp test edin.

temperature: Yanıt rastgeleliği. 0.0 deterministik, 1.0+ çok rastgele.

top_p: Nucleus sampling. 0.95 genellikle iyi başlangıç noktası.

repeat_penalty: Tekrar eden token cezası. 1.0 ceza yok, 1.1-1.3 arası önerilen.

Chat Template Yapılandırması

Her model ailesi farklı prompt formatı kullanıyor. Yanlış template sizi tutarsız ve kalitesiz yanıtlara mahkum eder. Popüler modeller için doğru template’ler:

# Mistral modelleri için konfigürasyon
cat > /opt/localai/models/mistral-7b-instruct.yaml << 'EOF'
name: mistral-7b-instruct
backend: llama
parameters:
  model: mistral-7b-instruct-v0.2.Q5_K_M.gguf
  context_size: 4096
  threads: 6
  temperature: 0.7
  top_p: 0.95
  top_k: 50
  repeat_penalty: 1.05

template:
  chat: |
    [INST] {{.Input}} [/INST]
  chat_message: |
    {{if eq .RoleName "user"}}[INST] {{.Content}} [/INST]{{end}}
    {{if eq .RoleName "assistant"}} {{.Content}}</s>{{end}}
    {{if eq .RoleName "system"}}<<SYS>>{{.Content}}<</SYS>>{{end}}
EOF
# ChatML formatı kullanan modeller için (Qwen, phi, bazı fine-tune'lar)
cat > /opt/localai/models/qwen-7b-chat.yaml << 'EOF'
name: qwen-7b-chat
backend: llama
parameters:
  model: qwen1_5-7b-chat-q5_k_m.gguf
  context_size: 8192
  threads: 4
  temperature: 0.7
  top_p: 0.8
  top_k: 20
  repeat_penalty: 1.05
  f16: false

template:
  chat: |
    <|im_start|>system
    {{.SystemPrompt}}<|im_end|>
    <|im_start|>user
    {{.Input}}<|im_end|>
    <|im_start|>assistant
EOF

GPU Offloading Konfigürasyonu

8GB veya daha fazla VRAM’iniz varsa GPU offloading ile dramatik hız artışı elde edersiniz. Kritik parametre gpu_layers:

cat > /opt/localai/models/llama-2-13b-chat-gpu.yaml << 'EOF'
name: llama-2-13b-chat
backend: llama
parameters:
  model: llama-2-13b-chat.Q4_K_M.gguf
  context_size: 4096
  threads: 4
  temperature: 0.7
  top_p: 0.95
  
  # GPU offloading ayarları
  gpu_layers: 35        # Kaç layer GPU'ya taşınsın
  main_gpu: 0           # Birincil GPU indeksi
  tensor_split: ""      # Multi-GPU için: "0.5,0.5"
  f16: true             # GPU için F16 kullan
  low_vram: false       # Düşük VRAM modeli

template:
  chat: |
    [INST] <<SYS>>
    {{.SystemPrompt}}
    <</SYS>>
    {{.Input}} [/INST]
EOF

gpu_layers değerini nasıl belirleyeceğiniz:

  • 13B Q4_K_M model için her layer yaklaşık 200-250MB VRAM ister
  • 8GB VRAM ile 35 layer rahat offload edilebilir
  • Tüm layerları GPU’ya atmak için -1 kullanın
  • Container loglarından hangi layer sayısında OOM aldığınızı izleyin
# GPU kullanımını izle
watch -n 1 nvidia-smi

# LocalAI loglarını takip et
docker logs -f localai_localai_1 2>&1 | grep -E "(layer|VRAM|GPU|error)"

Çoklu Model Yönetimi

Üretim ortamında tek model yetmez. Farklı görevler için farklı modeller çalıştırmanız gerekebilir:

# Model listesini kontrol et
ls -la /opt/localai/models/*.yaml

# Tüm konfigürasyonları doğrulama scripti
cat > /opt/localai/check-models.sh << 'EOF'
#!/bin/bash
MODELS_DIR="/opt/localai/models"
API_URL="http://localhost:8080"

echo "=== Model Dosyaları ==="
for yaml in $MODELS_DIR/*.yaml; do
  model_name=$(grep "^name:" $yaml | awk '{print $2}')
  model_file=$(grep "model:" $yaml | head -1 | awk '{print $2}')
  
  if [ -f "$MODELS_DIR/$model_file" ]; then
    size=$(du -h "$MODELS_DIR/$model_file" | cut -f1)
    echo "OK  | $model_name | $model_file ($size)"
  else
    echo "MISSING | $model_name | $model_file"
  fi
done

echo ""
echo "=== API Model Listesi ==="
curl -s $API_URL/v1/models | python3 -m json.tool 2>/dev/null || 
  echo "API erişilemiyor veya JSON parse hatası"
EOF

chmod +x /opt/localai/check-models.sh
./check-models.sh

Test ve Doğrulama

Model konfigürasyonu tamamlandıktan sonra LocalAI’yi yeniden başlatın ve testlere geçin:

# Servisi yeniden başlat
docker compose -f /opt/localai/docker-compose.yml restart

# Başlangıç loglarını izle
docker logs -f localai_localai_1 2>&1 | head -50

# Temel sağlık kontrolü
curl -s http://localhost:8080/readyz

# Yüklü modelleri listele
curl -s http://localhost:8080/v1/models | python3 -c "
import json, sys
data = json.load(sys.stdin)
for model in data.get('data', []):
    print(f"Model: {model['id']}")
"

İlk gerçek inference testini yapalım:

# Chat completion testi
curl -X POST http://localhost:8080/v1/chat/completions 
  -H "Content-Type: application/json" 
  -d '{
    "model": "llama-2-7b-chat",
    "messages": [
      {
        "role": "system",
        "content": "Sen yardımsever bir asistansın. Kısa ve öz cevap ver."
      },
      {
        "role": "user", 
        "content": "Linux sistemde disk kullanımını görmek için hangi komutu kullanmalıyım?"
      }
    ],
    "max_tokens": 150,
    "temperature": 0.7
  }' | python3 -m json.tool

Yanıt geliyorsa konfigürasyon doğru çalışıyor demektir. Gelmiyorsa önce log’lara bakın:

# Hata ayıklama için detaylı log
docker logs localai_localai_1 2>&1 | grep -i "error|warn|fatal" | tail -20

Yaygın Hatalar ve Çözümleri

“model not found” hatası: YAML dosyasındaki model: alanı ile fiziksel dosya adının tam eşleşip eşleşmediğini kontrol edin. Büyük/küçük harf farkı bile hataya yol açar.

“context exceeded” hatası: context_size değerini düşürün ya da isteğinizdeki max_tokens değerini azaltın.

OOM (Out of Memory) hatası: gpu_layers değerini düşürün veya daha küçük quantization kullanın. Q4_K_M yerine Q3_K_M deneyin.

Yavaş yanıt süresi: threads parametresini artırın, ancak toplam CPU çekirdeğini geçmeyin. context_size değerini düşürmek de yardımcı olur.

Bozuk/tekrarlayan çıktı: repeat_penalty değerini 1.1-1.3 arasına çekin. Yanlış chat template de bu belirtiye yol açar.

# Performans benchmark scripti
cat > /opt/localai/benchmark.sh << 'EOF'
#!/bin/bash
MODEL=${1:-"llama-2-7b-chat"}
PROMPT="Merhaba, kendini kısaca tanıtır mısın?"

echo "Model: $MODEL"
echo "Test başlıyor..."

START_TIME=$(date +%s%N)

RESPONSE=$(curl -s -X POST http://localhost:8080/v1/chat/completions 
  -H "Content-Type: application/json" 
  -d "{
    "model": "$MODEL",
    "messages": [{"role": "user", "content": "$PROMPT"}],
    "max_tokens": 100
  }")

END_TIME=$(date +%s%N)
ELAPSED=$(( (END_TIME - START_TIME) / 1000000 ))

echo "Yanıt süresi: ${ELAPSED}ms"
echo "$RESPONSE" | python3 -c "
import json, sys
data = json.load(sys.stdin)
usage = data.get('usage', {})
content = data['choices'][0]['message']['content']
print(f"Toplam token: {usage.get('total_tokens', 'N/A')}")
print(f"Yanıt: {content[:100]}...")
"
EOF

chmod +x /opt/localai/benchmark.sh
./benchmark.sh llama-2-7b-chat

Embedding Modeli Ekleme

RAG pipeline’ları veya semantik arama için embedding modellerine ihtiyacınız olacak. nomic-embed gibi küçük ve hızlı modeller bu iş için ideal:

# Embedding model konfigürasyonu
cat > /opt/localai/models/nomic-embed.yaml << 'EOF'
name: nomic-embed-text
backend: llama
parameters:
  model: nomic-embed-text-v1.5.Q8_0.gguf
  embeddings: true
  context_size: 2048
  threads: 4
  f16: false
EOF

# Embedding testi
curl -X POST http://localhost:8080/v1/embeddings 
  -H "Content-Type: application/json" 
  -d '{
    "model": "nomic-embed-text",
    "input": "Bu bir test cümlesidir."
  }' | python3 -c "
import json, sys
data = json.load(sys.stdin)
emb = data['data'][0]['embedding']
print(f'Embedding boyutu: {len(emb)}')
print(f'İlk 5 değer: {emb[:5]}')
"

Systemd ile Otomatik Başlatma

Docker Compose yerine doğrudan binary kullanıyorsanız ya da compose servisini system seviyesinde yönetmek istiyorsanız:

# Systemd service dosyası oluştur
cat > /etc/systemd/system/localai.service << 'EOF'
[Unit]
Description=LocalAI Service
After=docker.service
Requires=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/localai
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=300

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable localai
systemctl start localai
systemctl status localai

Güvenlik Notları

LocalAI varsayılan olarak authentication olmadan çalışır. Sunucunuz internete açıksa mutlaka önünde bir reverse proxy koyun ve API key ekleyin.

Nginx ile basit API key koruması:

# Nginx konfigürasyonu
cat > /etc/nginx/sites-available/localai << 'EOF'
server {
    listen 443 ssl;
    server_name ai.sunucunuz.com;
    
    location /v1/ {
        # API key kontrolü
        if ($http_authorization != "Bearer GIZLI_API_KEY_BURAYA") {
            return 401;
        }
        
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
        proxy_buffering off;
    }
}
EOF

Sonuç

GGUF modelleri LocalAI’de doğru konfigürasyon dosyasıyla birlikte kullanıldığında oldukça stabil çalışıyor. Özet olarak dikkat etmeniz gereken kritik noktalar:

  • Her model için ayrı YAML konfigürasyonu zorunlu
  • Chat template model ailesine göre değişiyor, yanlış template kötü sonuçlara yol açıyor
  • gpu_layers parametresi GPU offloading’i kontrol ediyor, VRAM’inize göre ayarlayın
  • threads değeri fiziksel çekirdeğinizi geçmemeli
  • Üretim ortamında API’nin önüne mutlaka authentication koyun

Buraya kadar anlattıklarımla temel bir LocalAI + GGUF kurulumu tamamlanmış oluyor. Bir sonraki adım olarak OpenAI uyumlu bu endpoint’i gerçek uygulamalarla entegre etmek veya birden fazla model arasında load balancing yapmak geliyor. Sunucunuzun kapasitesine göre kaç kullanıcıya aynı anda hizmet verebileceğiniz de ayrıca ölçümlenmeye değer bir konu. LocalAI thread ve context yönetimini iyi yapıyor ama paralel istek sayısı arttıkça davranışı izlemek önemli.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir