Wskazówki praktyczne: Od drobnej optymalizacji do precyzji: znaczne zmniejszenie
Krok po kroku praktyczne wskazówki: od drobnych dostosowań do maksymalnej precyzji – jak znacząco zmniejszyć liczbę kontraktów, sprawdzeń oraz miejsc na kod w projektach zastosowujących ten wzorzec.
To przewodnictwo pokazuje, jak odtworzyć proces od surowców do działającego systemu w ramach tematu: Od drobnej optymalizacji do precyzji: znaczące zmniejszenie halucynacji w Twoim pipeline RAG. Skupiamy się na krokach operacyjnych, wyraźnych sprawdzeniach oraz kodzie, który można bez problemu wdrożyć do repozytorium, bez konieczności domyślania się intencji.
1. Wprowadzenie
Na etapie wprowadzenia należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności domyślania się ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Podaj źródła fragmentów tekstu, które faktycznie stanowiły podstawę odpowiedzi – bez tych odniesień operatorzy nie będą mogli odróżnić halucynacji od braków w indeksowaniu.
You: What was the revenue from contracts with customers in 2024?
Assistant: The revenue was €179,058,000. ← Wrong! Correct answer is €159,088,000.
2. Dlaczego drobna optymalizacja?
W fazie drobnej kalibracji „2 Why” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy proces przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Należy podawać fragmenty tekstu, które faktycznie stanowiły podstawę odpowiedzi. Bez tych odniesień operatorzy nie mogą odróżnić halucynacji od luki w indeksowaniu.
Rozwiązanie: Drobna kalibracja za pomocą MLX
Aby dokonać drobnej optymalizacji rozwiązania w poszczególnych etapach, należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Konfigurację należy przechowywać poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić, nie musząc czytać całej struktury. Należy podawać konkretne fragmenty tekstu, na których opiera się odpowiedź. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od braku danych w indeksie.
3. Diagram architektury
W fazie 3 diagramu architektury należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy udokumentować zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Należy podać fragmenty tekstu, które faktycznie stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić halucynacji od luki w indeksowaniu.
┌─────────────────────────────────────────────────────────────────────────────┐
│ PART 3: FINE-TUNING WORKFLOW (M1) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Dataset 2. MLX Fine-Tuning │
│ ┌──────────────────┐ ┌────────────────────────────────────────────┐ │
│ │ Chart Images │─────▶│ Base Model (Qwen2-VL-2B) │ │
│ │ Q&A Pairs │ │ + LoRA Adapters (mlx_vlm.lora) │ │
│ │ (train.jsonl) │ │ + Unified Memory Training on Apple Silicon│ │
│ └──────────────────┘ └────────────────┬───────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ Fine-Tuned LoRA Adapters │ │
│ │ (./fine_tuned_adapters/) │ │
│ └────────────────┬─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ 3. Merge & Export to GGUF │ │
│ │ (mlx_vlm.fuse + convert_hf_to_gguf.py) │ │
│ └────────────────┬─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ 4. Deploy with Ollama │ │
│ │ ollama create my-chart-model │ │
│ │ (text.gguf + mmproj.gguf) │ │
│ └────────────────┬─────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ 5. Update rag_engine.py │ │
│ │ │ │
│ │ VISION_MODEL = "my-chart-model" # ← Change ONE line │ │
│ │ TEXT_MODEL = "llama3.2:3b" # Unchanged │ │
│ │ │ │
│ │ ✔ Existing app.py (from Part 2) automatically uses the new model! │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
4. Przygotowanie zestawu danych
W fazie 4 „Przygotowanie zestawu danych” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, powinien wskazywać na konkretną przyczynę, a nie na skomplikowaną strukturę procesu. Należy podawać konkretne fragmenty tekstu, które stanowią podstawę odpowiedzi. Bez tych odniesień operatorzy nie będą w stanie odróżnić fałszywych informacji od braków w indeksowaniu. W fazie 4 „Przygotowanie zestawu danych” należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy rejestrować czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Jasna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z wersji demonstracyjnej do środowiska współdzielonego.
Model sees: (Chart image)
Model reads: (Question)
Model learns: (Correct answer)
Źródła zestawu danych
Podczas prace na etapie źródeł zestawu danych najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Zmierz stopę odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko poprawiają słabą efektywność wyszukiwania.
Krok po kroku przygotowanie danych
Gdy przechodzisz przez etap krok po kroku przygotowania danych, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez ludzi oraz obsługa wiadomości błędnych stanowią część produktu, a nie elementy dodawane później. Zmierz stopień odzyskiwania informacji na ustalonej grupie pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe mechanizmy wyszukiwania.
Step 1: Create Raw Dataset → chart_dataset/raw_train.jsonl
Step 2: Convert to MLX Format → chart_dataset/train.jsonl
Step 3: Verify Dataset → Check that train.jsonl exists
Krok 1: Stworzenie surowego zestawu danych
Gdy przechodzisz przez Krok 1 – Stworzenie etapu, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany proces. Zmierz stopień przywoływania informacji na ustalonej serii pytań przed dostosowywaniem promptów. Częste zmiany promptów rzadko naprawiają słabe możliwości wyszukiwania. Gdy przechodzisz przez Krok 1 – Stworzenie etapu, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do wspólnych środowisk.
# download_chartqa.py
from datasets import load_dataset
import json
import os
os.makedirs("chart_dataset", exist_ok=True)
# Download ChartQA dataset
dataset = load_dataset("ahmed-masry/ChartQA", split="train")
# Convert to flat format with standard keys
converted = []
for item in dataset:
converted.append({
"image": item["imgname"], # Path to chart image
"question": item["query"],
"answer": item["label"]
})
# Save as raw dataset
with open("chart_dataset/raw_train.jsonl", "w") as f:
for entry in converted:
f.write(json.dumps(entry) + "\n")
print(f"✅ Converted {len(converted)} ChartQA samples to chart_dataset/raw_train.jsonl")
README.md: 100%|█████████████████████████████████████████████| 2.12k/2.12k [00:00<00:00, 3.72MB/s]
Warning: You are sending unauthenticated requests to the HF Hub. Please set a HF_TOKEN to enable higher rate limits and faster downloads.
data/train-00000-of-00003.parquet: downloading bytes: ████████████████████████| 213MB, 17.3MB/s
......
Generating test split: 100%|████████████████████████| 2500/2500 [00:00<00:00, 20517.87 examples/s]
✅ Converted 28299 ChartQA samples to raw_train.jsonl
Opcja B: Generowanie danych syntetycznych
Etap generowania danych syntetycznych w Opcji B działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny haseł oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Oddziel zasadę dzielenia na fragmenty od zasady pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w przypadku zmian wskaźników jakości.
# generate_synthetic_data.py
import json
import matplotlib.pyplot as plt
import numpy as np
import os
os.makedirs("chart_dataset/images", exist_ok=True)
dataset = []
for i in range(100):
categories = ['Q1', 'Q2', 'Q3', 'Q4']
values = np.random.randint(100, 500, 4)
plt.figure()
plt.bar(categories, values)
plt.title(f"Quarterly Revenue {i}")
plt.savefig(f"chart_dataset/images/chart_{i:03d}.png")
plt.close()
dataset.append({
"image": f"images/chart_{i:03d}.png",
"question": "Which quarter had the highest revenue?",
"answer": f"Q{np.argmax(values) + 1} with ${max(values)} million"
})
with open("chart_dataset/raw_train.jsonl", "w") as f:
for entry in dataset:
f.write(json.dumps(entry) + "\n")
print("✅ Generated 100 synthetic samples in chart_dataset/raw_train.jsonl")
Krok 2: Przekształcenie do formatu MLX
Krok 2 – Przekształcenie w etap – działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przypadek, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań przed rozszerzeniem zakresu. Zdokumentuj zarówno pomyślny, jak i awaryjny scenariusz działania. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej nie powinna zmuszać do przepisania drugiej, gdy zmieniają się metryki jakości.
# convert_to_mlx_format.py
import json
import os
def convert_raw_to_mlx_format(data_dir="chart_dataset"):
"""
Convert raw dataset to MLX format.
Input: chart_dataset/raw_train.jsonl
Output: chart_dataset/train.jsonl (MLX-compatible)
"""
raw_file = os.path.join(data_dir, "raw_train.jsonl")
out_file = os.path.join(data_dir, "train.jsonl")
if not os.path.exists(raw_file):
print(f"❌ {raw_file} not found. Run download_chartqa.py or generate_synthetic_data.py first.")
return None
dataset = []
with open(raw_file, "r") as f:
for line in f:
item = json.loads(line)
# Build full image path
img_str = item["image"]
image_path = img_str if img_str.startswith(data_dir) else os.path.join(data_dir, img_str)
dataset.append({
"images": [image_path], # MUST be a list
"messages": [
{"role": "user", "content": item["question"]},
{"role": "assistant", "content": item["answer"]}
]
})
with open(out_file, "w") as f:
for entry in dataset:
f.write(json.dumps(entry) + "\n")
print(f"✅ Converted {len(dataset)} samples to {out_file}")
return dataset
if __name__ == "__main__":
convert_raw_to_mlx_format()
python convert_to_mlx_format.py
Krok 3: Weryfikacja zestawu danych
Krok 3: Weryfikacja skuteczności etapu sprawdza się najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden udany przypadek, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Oddziel zasady dzielenia na fragmenty od zasad pobierania danych. Zmiana jednych nie powinna zmuszać do przepisywania drugich, gdy zmieniają się metryki jakości.
ls -la chart_dataset/
chart_dataset/
├── raw_train.jsonl # Raw Q&A pairs (flat keys)
├── train.jsonl # MLX-formatted (overwritten by prepare_mlx_dataset)
└── images/ # Chart images
📌 Important: Before running the fine-tuning command, ensure train.jsonl exists in your dataset directory.
If you see a FileNotFoundError, you haven't run the conversion step yet.
5. Dopełnianie ustawień za pomocą MLX
Faza 5 Fine-Tuning with MLX działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przykład transkrypcji, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Rozdziel politykę dzielenia na fragmenty od polityki wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
Wymagania wstępne
Etap wstępnych wymagań działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Rozdziel politykę dzielenia na fragmenty od polityki wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
# For fine-tuning vision models
pip install mlx-vlm
# For merging adapters (needed after training)
pip install mlx-lm
Rozpocznij dopasowanie
Etap drobnej optymalizacji działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Przechowuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej w przypadku zmian wskaźników jakości.
python -m mlx_vlm.lora \
--model Qwen/Qwen2-VL-2B-Instruct \
--dataset ./chart_dataset/train.jsonl \
--iters 1000 \
--batch-size 1 \
--lora-rank 8 \
--gradient-accumulation-steps 4 \
--max-seq-length 512
Rozumienie wyników szkolenia
Etap wyjściowy szkolenia zrozumienia funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrola przez ludzi oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dopracowywane później. Oddziel zasadę dzielenia na fragmenty od zasady wyszukiwania. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
INFO:__main__:Loading model from Qwen/Qwen2-VL-2B-Instruct
Fetching 11 files: 100%|████████████████████████████████████████| 11/11 [00:00<00:00, 1465.47it/s]
Download complete: : | 0.00B
Reconstruction complete: | | 0.00B / 0.00B
INFO:__main__:Loading dataset from ./chart_dataset/train.jsonl
INFO:__main__:Setting up LoRA
#trainable params: 9.232384 M || all params: 2208.9856 M || trainable%: 0.418%
INFO:__main__:Setting up optimizer
INFO:__main__:Training model (sft)
Starting training..., iterations: 1000
No validation dataset provided — training will run without validation.
......
Iter 120: Train loss 7.77592850, Learning Rate 2.000e-05,
It/sec 0.242, Tokens/sec 103.862, Trained Tokens 51480, Peak mem 8.069 GB
.....
Saved final adapter weights to adapters.safetensors.
INFO:__main__:Training completed! Model saved to adapters.safetensors
6. Rozwiązywanie problemów
Etap rozwiązywania problemów działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Rozdziel politykę dzielenia na fragmenty od polityki pobierania danych. Zmiana jednej z nich nie powinna zmuszać do przepisywania drugiej, gdy zmieniają się metryki jakości.
Błąd „Dane nie znalezione”
Etap błędu „Dane nie znalezione” działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy.
FileNotFoundError: Couldn't find any data file at .../chart_dataset/train.jsonl
python convert_to_mlx_format.py
Błąd „Brak pamięci” (OOM)
RuntimeError: [METAL] Command buffer execution failed: Insufficient Memory
python -m mlx_vlm.lora \
--model Qwen/Qwen2-VL-2B-Instruct \
--dataset ./chart_dataset/train.jsonl \
--iters 1000 \
--batch-size 1 \ # ← Reduced from 4 to 1
--lora-rank 4 \ # ← Reduced from 8 to 4
--gradient-accumulation-steps 8 \ # ← Added
--max-seq-length 256 # ← Added
Ścieżka adaptera nie znaleziona
FileNotFoundError: The adapter path does not exist: fine_tuned_adapters
ls -la adapters.safetensors adapter_config.json
python -m mlx_lm fuse \
--model Qwen/Qwen2-VL-2B-Instruct \
--adapter-path . \
--save-path ./fine_tuned_model_merged
Błąd niekompletnej pamięci cache
IncompleteSnapshotError: The cached snapshot for 'Qwen/Qwen2-VL-2B-Instruct' is incomplete
rm -rf ~/.cache/huggingface/hub/models--Qwen--Qwen2-VL-2B-Instruct
7. Ile czasu zajmie szkolenie?
Total Time (seconds) = Total Iterations ÷ It/sec
Total Time (minutes) = Total Time (seconds) ÷ 60
1000 ÷ 0.242 = 4,132 seconds
4,132 ÷ 60 = ~69 minutes
8. Łączenie adapterów LoRA
python -m mlx_lm fuse \
--model Qwen/Qwen2-VL-2B-Instruct \
--adapter-path . \
--save-path ./fine_tuned_model_merged
9. Eksport do GGUF dla Ollamy
Krok 1: Eksport MLX do formatu Hugging Face
#!/usr/bin/env python3
import mlx_lm
from mlx_lm import load, save
model, tokenizer, config = load("./fine_tuned_model_merged")
save(model, tokenizer, config, "./hf_export")
print("✅ Exported to ./hf_export")
python export_to_hf.py
Krok 2: Przekształcenie do GGUF
# Clone llama.cpp (if not already done)
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
# Convert text model
python convert_hf_to_gguf.py ../hf_export \
--outfile chart_model-text.gguf \
--outtype f16
Krok 3: Przekształcenie projektora wizualnego
python convert_hf_to_gguf.py ../hf_export \
--outfile chart_model-mmproj.gguf \
--outtype f16 \
--mmproj
ls ~/.cache/huggingface/hub/models--Qwen--Qwen2-VL-2B-Instruct/snapshots/
# sample output . You'll see a hash directory (e.g., 895c3a49...)
# 895c3a49bc3fa70a340399125c650a463535e71c
cd llama.cpp
# replace <hash> with the output above (e.g., 895c3a49...)
python convert_hf_to_gguf.py ~/.cache/huggingface/hub/models--Qwen--Qwen2-VL-2B-Instruct/snapshots/<hash>/ \
--outfile base-mmproj.gguf \
--outtype f16 \
--mmproj
10. Wdrożenie z użyciem Ollamy
FROM ./chart_model-text.gguf
FROM ./chart_model-mmproj.gguf
PARAMETER temperature 0.2
Stworzenie modelu
ollama create my-chart-model -f Modelfile
Weryfikacja modelu
ollama list
# output :
# NAME ID SIZE MODIFIED
# my-chart-model:latest b3fd6d8fd742 4.4 GB 7 hours ago
# qwen2.5vl:3b fb90415cde1e 3.2 GB 9 days ago
# llama3.2:3b a80c4f17acd5 2.0 GB 10 days ago
# llama3:latest 365c0bd3c000 4.7 GB 3 months ago
# You should see my-chart-model in the list.
Testowanie modelu
ollama run my-chart-model "What is 2+2?"
11. Integracja z istniejącą aplikacją RAG
# In rag_engine.py (from Parts 1 & 2)
# Before:
VISION_MODEL = "qwen2.5vl:3b"
# After:
VISION_MODEL = "my-chart-model" # Your fine-tuned model
TEXT_MODEL = "llama3.2:3b" # Unchanged
python app.py
12. Ocena: model podstawowy vs. dopracowany
Porównanie
13. Podsumowanie
Pobierz pełny kod
git clone https://github.com/froilan-sia/m1_multimodal_rag.git
cd m1_multimodal_rag
Skontaktuj się ze mną
Lista kontrolna operacyjna
Literatura pokrewna
- Praktyczne notatki: Doprecyzowanie stało się tanie. Twój agent nadal musi nauczyć się prawie wszystkiego — Szczegółowy przewodnik po Praktycznych notatkach: Doprecyzowanie stało się tanie. Twój agent nadal musi nauczyć się prawie wszystkiego: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów stosujących ten wzorzec.
- Praktyczne notatki: Co właściwie odkrywa agent diffing-modelu z — Szczegółowy przewodnik po Praktycznych notatkach: Co właściwie odkrywa agent diffing-modelu z: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów stosujących ten wzorzec.