Strona główna / Artykuły

Praktyczny lokalny LLM w 30 minut: programowanie, pytania i odpowiedzi w dokumentach oraz głos

Praktyczny lokalny LLM w 30 minut dzięki Ollama, Qwen3 i Whisper.cpp: asystent do programowania, system RAG do przetwarzania notatek oraz funkcja nagrywania głosu offline, dostosowana do pojemności pamięci.

Wydawca: REACTAPP.TOP14 min czytania3183 słów

Źródła: Run a Useful Local LLM in 30 Minutes (Coding, RAG, Voice)

Model lokalny może odpowiedzieć na rzeczywiste pytanie z zakresu programowania, nawet gdy sieć jest odłączona, na laptopie, który już znajduje się na biurku. Konfiguracja trwa około ośmiu minut, a rachunek miesięczny jest zerowy. Wystarczy prompt taki jak poniżej, aby zobaczyć, jak to działa.

$ ollama run qwen3:8b
>>> rewrite this function to use async/await

Jakość jest zaskakująca. Choć nie dorównuje najlepszym modelom chmurowym pod względem złożonych, wieloetapowych rozumowań, to wystarczająco niezawodnie radzi sobie z zwykłymi zadaniami inżynieryjnymi, dzięki czemu różnica pomiędzy zabawką na weekend a funkcjonalnym narzędziem znacznie się zmniejszyła.

Trzy zmiany w ciągu ostatnich półtora roku sprawiły, że stało się to praktyczne. Pliki modeli skurczyły się do rozmiarów dostępnych w zwykłej pamięci RAM: Qwen 3 dostarczany jest w wersji z 8 miliardami parametrów o wielkości około 5 GB. Qwen3-Coder, wydany w lutym 2026 roku, osiąga 70,6 procent wyniku na SWE-bench. Został zweryfikowany dzięki architekturze typu mixture-of-experts o pojemności 30 miliardów parametrów, która aktywuje jedynie 3 miliardy parametrów na token. A instalacja przeszła z bałaganu środowisk Python na jeden plik binarny, dzięki Ollamie.

Poniżej znajdują się trzy oddzielne wersje, każda trwająca około pół godziny: asystent do programowania wewnątrz edytora, skrypt w Pythonie, który odpowiada na pytania dotyczące folderu z dokumentami, oraz pętla głosowa, która słucha i odpowiada. Wszystkie mają wspólną pięciominutową bazę, a następnie się różnią, więc rozsądnym krokiem jest wybranie tej najbliższej codziennej pracy i odłożenie pozostałych na później.

Wspólna baza

Każda z tych wersji wymaga silnika inferencji oraz zestawu wag modelu.

Ollama pełni rolę tego silnika. Zajmuje się różnicami w sprzęcie, sprawdzając, czy komputer ma kartę graficzną NVIDIA, chip Apple Silicon, czy tylko procesor CPU, i przygotowuje odpowiedni graf wykonywania. Działa w tle i oferuje lokalną API HTTP, która zachowuje się jak punkty końcowe dużych dostawców chmury.

Instalacja zależy od platformy. Na macOS zadanie to wykonuje Homebrew:

brew install ollama

Linux ma skrypt instalacyjny:

curl -fsSL https://ollama.com/install.sh | sh

Użytkownicy Windows mogą pobrać instalator MSI z strony internetowej Ollamy.

Gdy silnik jest już zainstalowany, pozostaje model. Bazowym modelem jest qwen3:8b, który wymaga około 5 GB miejsca na dysku i swobodnie mieści się w 16 GB pamięci RAM. Bez oddzielnej karty graficznej Ollama korzysta z obliczeń na procesorze, osiągając prędkość około 8 do 12 tokenów na sekundę, co nadal zapewnia doskonałą czytelność tekstu.

Pobierz go:

ollama pull qwen3:8b

Następnie sprawdź, czy wszystko działa poprawnie, przeprowadzając szybki test:

ollama run qwen3:8b "Write a python script to reverse a string."

Odpowiedź jest wysyłana strumieniowo do terminala. W tle Ollama ładuje plik GGUF – format, który mapuje wagi z dysku bezpośrednio do pamięci RAM, dzięki czemu na monitorze systemowym widać, jak pamięć wzrasta mniej więcej o rozmiar tego pliku.

Komputer z 8 GB pamięci RAM lub mniej zacznie korzystać z wymiany danych na dysku, co spowoduje znaczne spowolnienie działania. Dla takich przypadków lepszym wyborem są qwen3:4b lub gemma3:4b. Przy karcie graficznej o pojemności 24 GB istnieje możliwość użycia qwen3:14b jako następnego kroku w rozwoju.

Szlak A: asystent programistyczny w edytorze

Każdy, kto pracuje w edytorze kodu, uzyska tu najszybsze korzyści. Celem jest połączenie lokalnego modelu z VS Code w celu przeprowadzania refaktoryzacji, dodawania dokumentacji oraz tworzenia szablonów.

Ogólny model Qwen 3 jest kompetentny, ale praca z kodem lepiej radzi sobie dzięki specjalistycznemu szkoleniu. Od maja 2026 roku Qwen3-Coder jest najsilniejszym wszechstronnym lokalnym kodownikiem, osiągającym 70,6 procent wyniku na SWE-bench Verified oraz 44,3 procent na SWE-Bench Pro. Jego całkowita liczba parametrów wynosi 30 miliardów, ale tylko 3 miliardy z nich jest aktywnych przy każdym tokenie, dzięki czemu mieści się w 24 GB pamięci VRAM lub działa płynnie na komputerze z serii M z 32 GB pamięci zintegrowanej.

Laptop z 16 GB pamięci, bez oddzielnej karty graficznej, prawdopodobnie będzie miał trudności z obsługą modelu o 30 miliardach parametrów. Alternatywą jest qwen2.5-coder:7b, który wymaga 4,7 GB pamięci i nadal osiąga około 92 procent wyniku na HumanEval.

# For 24GB+ VRAM or 32GB+ Mac Unified Memory
ollama pull qwen3-coder:30b

# For 16GB RAM laptops
ollama pull qwen2.5-coder:7b

Edytor potrzebuje interfejsu użytkownika do komunikacji z modelem. Cline, rozszerzenie VS Code z ponad 5 milionami zainstalowań, potrafi czytać pliki, proponować różnice między wersjami oraz wykonywać polecenia w terminalu. Można je znaleźć, wyszukując je w sklepie z rozszerzeniami pod ich nazwą.

Jedna pułapka wymaga uwagi. Cline zawiera długi prompt systemowy, który wyjaśnia, jak formatować różnice, czytać strukturę plików oraz korzystać z narzędzi, a ten prompt często zawiera ponad 25 000 tokenów, zanim zostanie dołączony jakikolwiek kod. Domyślne okno kontekstowe Ollamy dla modeli Qwen 3 wynosi 40 000 tokenów. Po otwarciu kilku plików ich łączna liczba łatwo przekracza tę wartość, wtedy Ollama bez uprzedzenia skraca prompt. W rezultacie model traci instrukcje dotyczące formatowania, ignoruje zasady i generuje zwykły tekst zamiast poprawnych różnic między wersjami.

Rozwiązaniem jest dostosowany Modelfile, który zmusza do użycia większego okna kontekstowego.

Modelfile dostosowany do Cline

Zapisz poniższy tekst w katalogu roboczym jako plik o nazwie Modelfile.

# Modelfile — cline-tuned qwen3-coder
# Save as: ./Modelfile

FROM qwen3-coder:30b

# Cline's system prompt is ~25-30K tokens before your code is added.
# Ollama's default num_ctx for Qwen 3 is 40K, but Cline ships an
# expanded system prompt in v3+ that comfortably exceeds it on any
# real task. 65536 is the safe floor for serious use; 131072 if
# you have RAM/VRAM to spare.
PARAMETER num_ctx 65536

# Code edits want low-variance output. The default 0.7 is too loose.
PARAMETER temperature 0.2

# Stop after the model's natural turn. Cline parses this.
PARAMETER stop "<|im_end|>"

Stwórz model na jego podstawie za pomocą Ollama CLI, a następnie sprawdź, czy ustawienie kontekstu zadziałało:

# Build the Cline-tuned model from the Modelfile in the current dir
ollama create qwen3-coder-cline -f ./Modelfile

# Verify the context window actually took
ollama show qwen3-coder-cline --modelfile | grep num_ctx
# Expected output:  PARAMETER num_ctx 65536

# Sanity-check it answers
ollama run qwen3-coder-cline "write a python one-liner to read /etc/hostname"

W VS Code otwórz panel poleceń przy użyciu Cmd+Shift+P i wybierz opcję ustawień Cline. Skieruj go na lokalny silnik:

API Provider:      Ollama
Base URL:          http://localhost:11434
Model:             qwen3-coder-cline
Context Window:    65536

Wartość okna kontekstowego w interfejsie graficznym musi dokładnie odpowiadać wartości num_ctx w pliku modelu. Jeśli jest niższa, Cline zakłada mniejsze okno i po cichu ogranicza liczbę wysyłanych plików.

Aby to wypróbować, otwórz plik Python z funkcją synchroniczną, otwórz panel czatu Cline i poproś o przekształcenie kodu na format async/await. Cline odczytuje plik, wysyła go do lokalnego modelu Qwen3-Coder, otrzymuje odpowiedź i pokazuje czystą różnicę w edytorze. Akceptacja odbywa się jednym kliknięciem, a cała operacja przebiega offline.

Ta konfiguracja radzi sobie z przekształcaniami pojedynczych plików, testowaniem izolowanych funkcji oraz generowaniem szablonów. Testy przeprowadzane przez społeczność wskazują, że na zadaniach o wąskim zakresie osiąga ona około 70 do 85 procent jakości najnowocześniejszych rozwiązań chmurowych.

Ulega awarii przy dużych zmianach w architekturze obejmujących wiele plików. Przeniesienie projektu Flask składającego się z dwudziestu plików na FastAPI jest momentem, w którym to się nie udaje: wątek ginie, pojawiają się fałszywe importy, a baza kodu zostaje uszkodzona. Prace tego rozmiaru nadal pasują do modeli chmurowych typu frontier. Natomiast przy dziesiątkach małych, żmudnych edycji wykonywanych codziennie wystarcza lokalny model.

Szlak B: wyszukiwanie w własnych dokumentach

Taki przypadek dotyczy folderu z notatkami w formacie markdown, transkrypcjami spotkań lub dokumentacją projektu, który jest przeszukiwany ręcznie. Cały proces mieści się w około 60 liniach zwykłego Pythona, wykorzystującym jedynie klienta Ollama i numpy.

Model embedding konwertuje tekst na wektory. Nomic Embed Text v1.5 ma 137 milionów parametrów, wytwarza wektory o wymiarze 768, zajmuje mniej niż 300MB, obsługuje kontekst składający się z 8192 tokenów i osiąga dobre wyniki w testach wydajnościowych MTEB.

Pobierz model embeddingowy i zainstaluj pakiety Pythona:

llama pull nomic-embed-text
pip install ollama numpy

Następnie zapisz skrypt jako rag.py.

"""Local RAG over a folder of notes — Ollama embeddings + numpy cosine.

No vector DB. For a few hundred docs, an in-memory list + numpy is
faster to set up and fast enough to run. Swap in sqlite-vec when
the corpus outgrows it (typically past ~5000 chunks).

Setup:
    ollama pull qwen3:8b
    ollama pull nomic-embed-text
    pip install ollama numpy

Run:
    python rag.py ./notes "what did the team decide about pricing?"
"""
from __future__ import annotations
import glob
import os
import sys

import numpy as np
import ollama

EMBED_MODEL = "nomic-embed-text"
CHAT_MODEL = "qwen3:8b"
CHUNK_WORDS = 400          # ~500 tokens; fits 4 chunks in an 8K context
TOP_K = 3


def load_chunks(folder: str) -> list[str]:
    """Read every .md / .txt under folder, split into ~CHUNK_WORDS chunks."""
    chunks: list[str] = []
    for path in glob.glob(os.path.join(folder, "**/*"), recursive=True):
        if not path.endswith((".md", ".txt")):
            continue
        with open(path, encoding="utf-8") as f:
            words = f.read().split()
        for i in range(0, len(words), CHUNK_WORDS):
            chunk = " ".join(words[i : i + CHUNK_WORDS])
            if chunk.strip():
                chunks.append(chunk)
    return chunks


def embed(texts: list[str]) -> np.ndarray:
    """Embed a batch of texts via Ollama. Returns an (N, D) matrix."""
    resp = ollama.embed(model=EMBED_MODEL, input=texts)
    return np.array(resp["embeddings"], dtype=np.float32)


def top_k_indices(
    query_vec: np.ndarray, doc_mat: np.ndarray, k: int
) -> list[int]:
    """Return indices of the k most cosine-similar rows in doc_mat.

    The trick: if both vectors are unit-length (norm == 1), their
    dot product equals their cosine similarity. So we normalize
    once, then one matrix multiply gives a similarity score for
    every chunk against the query — no Python loop needed.
    """
    # Normalize query and every chunk to unit length.
    # The 1e-8 prevents division by zero on a zero vector.
    q = query_vec / (np.linalg.norm(query_vec) + 1e-8)
    d = doc_mat / (np.linalg.norm(doc_mat, axis=1, keepdims=True) + 1e-8)

    # One matmul across all chunks: scores[i] = cos(query, chunk_i).
    scores = d @ q

    # Sort descending, take the first k indices.
    return np.argsort(scores)[::-1][:k].tolist()


def answer(query: str, chunks: list[str], doc_mat: np.ndarray) -> str:
    """Retrieve top-K chunks, stuff them into a prompt, generate."""
    q_vec = embed([query])[0]
    idx = top_k_indices(q_vec, doc_mat, k=TOP_K)
    context = "\n\n---\n\n".join(chunks[i] for i in idx)

    prompt = (
        "Answer the question using ONLY the context below. "
        "If the context does not contain the answer, say so plainly.\n\n"
        f"CONTEXT:\n{context}\n\nQUESTION: {query}"
    )
    resp = ollama.chat(
        model=CHAT_MODEL,
        messages=[{"role": "user", "content": prompt}],
    )
    return resp["message"]["content"]


if __name__ == "__main__":
    if len(sys.argv) != 3:
        sys.exit('usage: python rag.py <folder> "<question>"')

    folder, query = sys.argv[1], sys.argv[2]

    chunks = load_chunks(folder)
    if not chunks:
        sys.exit(f"no .md or .txt files found under {folder}")

    print(f"indexing {len(chunks)} chunks...")
    doc_mat = embed(chunks)

    print(answer(query, chunks, doc_mat))

Skieruj go na katalog z notatkami i zadaj pytanie:

python rag.py ~/Documents/meeting_notes "what did the team decide about pricing?"

Skrypt przegląda folder, czyta pliki i dzieli je na fragmenty po 400 słów. Pełna lista tych fragmentów jest wysyłana do punktu końcowego embeddingów Ollamy w jednej partii. Dla każdego pytania wektor zapytania jest porównywany z wektorem każdego dokumentu za pomocą podobieństwa kosinowego.

Trzy najlepsze fragmenty są wstawiane do promptu generacyjnego, a model qwen3:8b pisze odpowiedź. Jedno z poleceń w tym promptie jest ścisłe: należy odpowiadać wyłącznie na podstawie dostarczonego kontekstu i jasno zaznaczyć, jeśli kontekst nie zawiera odpowiedzi. Modele lokalne łatwo tworzą pomocnie brzmiące kłamstwa, gdy wyszukiwanie nic nie zwraca, a to polecenie zmusza je do przyznania się do niewiedzy.

To nie jest funkcja pobierania danych z produkcji. Podział tekstu na fragmenty to uproszczony sposób liczenia znaków, który czasami dzieli zdanie na dwie części. Embeddingi znajdują się w pamięci i znikają po zakończeniu pracy, dlatego korpus musi być ponownie zembedowany przy każdym uruchomieniu. Gdy zbiór dokumentów przekroczy kilka tysięcy, a proces startowy stanie się uciążliwy, zastąpienie macierzy numpy przez sqlite-vec umożliwia przechowywanie wektorów w lokalnym pliku SQLite. Do notatek osobistych wystarczy krótki skrypt.

Ścieżka C: pętla głosowa

Aby rozmawiać z modelem bez pisania i bez wysyłania dźwięku do usługi chmurowej, ta ścieżka tworzy kompletną pętlę głos do głosu na lokalnym sprzęcie.

Kanał komunikacji składa się z trzech elementów: konwersji mowy na tekst do transkrypcji dźwięku z mikrofonu, modelu LLM do tworzenia odpowiedzi oraz konwersji tekstu na mowę do jej odczytania na głos.

Transkrypcja wykorzystuje Whisper.cpp, silnie zoptymalizowaną wersję w języku C++ narzędzia Whisper firmy OpenAI, która działa na CPU, Apple Metal oraz NVIDIA CUDA. Do konwersji dźwięku wymagana jest zależność od ffmpeg. Na macOS:

brew install whisper-cpp ffmpeg

W systemie Linux należy zainstalować ffmpeg za pomocą menedżera pakietów, sklonować repozytorium whisper.cpp i uruchomić make.

Whisper.cpp wymaga wag w formacie GGML. Plik ggml-base.en.bin o wielkości około 150MB jest dostępny w oficjalnym repozytorium Hugging Face i zapewnia szybką oraz dokładną syntezę mowy w języku angielskim. Dla innych języków lub wyższej dokładności alternatywą jest ggml-large-v3.bin. Umieść plik w dobrze znanym folderze, np. ~/models/.

Dźwięk wygenerowany przez system pochodzi z Kokoro ONNX – lekkiego silnika TTS, którego wagy wynoszą około 300MB i który umożliwia syntezę mowy niemal w czasie rzeczywistym na zwykłym procesorze. Wymaga on obecnie wersji Pythona od 3.10 do 3.13 i nie instaluje się na wersji 3.14.

pip install -U sounddevice ollama kokoro-onnx

Skrypt pipeline

Zapisz poniższy tekst jako voice.py i zmień ścieżkę WHISPER_MODEL tak, aby wskazywała na właśnie pobraany plik GGML.

"""Local voice loop — mic → whisper.cpp → Ollama → Kokoro → speaker.

Everything runs offline. Nothing leaves the machine.

Setup:
    brew install whisper-cpp ffmpeg                  # macOS
    # (Linux: apt install ffmpeg; build whisper.cpp from source)

    pip install -U sounddevice ollama kokoro-onnx

    # Whisper GGML model — pick one:
    #   ggml-base.en.bin   (~150MB, fast, English-only)
    #   ggml-large-v3.bin  (~3GB, accurate, multilingual)
    # Download from https://huggingface.co/ggerganov/whisper.cpp

    # Kokoro model files auto-download to ~/.cache/kokoro-onnx/
    # on first run, or grab them manually from
    # https://github.com/thewh1teagle/kokoro-onnx/releases

Run:
    python voice.py
"""
from __future__ import annotations
import subprocess
import tempfile
import wave
from pathlib import Path

import sounddevice as sd
import ollama
from kokoro_onnx import Kokoro

WHISPER_MODEL = Path.home() / "models" / "ggml-base.en.bin"
CHAT_MODEL = "qwen3:8b"
KOKORO_VOICE = "af_sarah"      # see kokoro voices.json for all options
SAMPLE_RATE = 16000            # whisper.cpp requires 16kHz mono
RECORD_SECONDS = 5

# Kokoro auto-downloads the model files on first instantiation.
kokoro = Kokoro("kokoro-v1.0.onnx", "voices-v1.0.bin")


def record() -> Path:
    """Record from the default mic, write a 16kHz mono WAV, return its path."""
    print(f"listening for {RECORD_SECONDS}s...")
    audio = sd.rec(
        int(RECORD_SECONDS * SAMPLE_RATE),
        samplerate=SAMPLE_RATE,
        channels=1,                    # mono
        dtype="int16",                 # 16-bit PCM is what wave.open expects
    )
    sd.wait()                          # block until recording finishes

    # Fixed path in the system tempdir — overwritten each invocation.
    wav_path = Path(tempfile.gettempdir()) / "voice_in.wav"
    with wave.open(str(wav_path), "wb") as w:
        w.setnchannels(1)              # mono
        w.setsampwidth(2)              # 2 bytes per sample == int16
        w.setframerate(SAMPLE_RATE)    # 16 kHz — whisper.cpp's required rate
        w.writeframes(audio.tobytes())
    return wav_path


def transcribe(wav_path: Path) -> str:
    """Run whisper.cpp on a WAV file, return the transcript text."""
    result = subprocess.run(
        [
            "whisper-cli",
            "-m", str(WHISPER_MODEL),
            "-f", str(wav_path),
            "-otxt",                   # write the transcript to <input>.txt
            "-np",                     # suppress progress prints on stdout
        ],
        capture_output=True,
        text=True,
        timeout=60,
    )
    if result.returncode != 0:
        raise RuntimeError(f"whisper-cli failed: {result.stderr}")

    # -otxt writes the transcript next to the input file, with .txt
    # tacked onto the existing name — so /tmp/voice_in.wav becomes
    # /tmp/voice_in.wav.txt (same directory, same stem, extra suffix).
    txt_path = wav_path.with_suffix(wav_path.suffix + ".txt")
    return txt_path.read_text(encoding="utf-8").strip()


def respond(text: str) -> str:
    """Send the transcript to the local LLM, return the reply."""
    resp = ollama.chat(
        model=CHAT_MODEL,
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a voice assistant. Keep replies to one or "
                    "two short sentences. No markdown, no lists."
                ),
            },
            {"role": "user", "content": text},
        ],
    )
    return resp["message"]["content"]


def speak(text: str) -> None:
    """Synthesize the reply with Kokoro and play it back."""
    samples, sample_rate = kokoro.create(
        text, voice=KOKORO_VOICE, speed=1.0, lang="en-us"
    )
    sd.play(samples, sample_rate)
    sd.wait()


if __name__ == "__main__":
    wav = record()
    heard = transcribe(wav)

    if not heard:
        print("nothing heard. exiting.")
        raise SystemExit(0)

    print(f"you said: {heard}")
    reply = respond(heard)
    print(f"model:    {reply}")
    speak(reply)

Uruchomienie skryptu powoduje, że przez pięć sekund nasłuchuje on, transkrybuje treść, generuje odpowiedź i ją odczytuje. Podczas pierwszego uruchomienia następuje pauza, podczas której Kokoro pobiera swoje pliki ONNX do katalogu ~/.cache/kokoro-onnx/.

Trzy decyzje projektowe mają większe znaczenie, niż się wydaje. Nagrywanie w formacie mono przy częstotliwości 16 kHz jest obowiązkowe – Whisper został wytrenowany na dźwięku o tej częstotliwości, a mikrofony o standardowej częstotliwości 44,1 kHz generują fałszywy tekst lub puste wyniki. Uruchamianie whisper-cli jako odrębnego procesu zamiast jako modułu w Pythonie pozwala uniknąć konfliktów dostępu oraz problemów z rozszerzeniami typu C, a flaga odpowiadająca za wyświetlanie tekstu zapisuje transkrypcję do pliku, dzięki czemu nie trzeba analizować standardowego wyjścia. Prompty systemowe wyraźnie zabraniają używania markdown, ponieważ Kokoro odczytuje gwiazdki na głos, a sformatowana odpowiedź psuje doświadczenie użytkownika.

Pętla obsługuje tylko jedną rundę rozmowy. Nie przesyła plików audio w czasie rzeczywistym ani nie przechowuje historii rozmów. Prawdziwy agent konwersacyjny dodałby funkcję wykrywania aktywności głosowej, aby wiedzieć, kiedy mowa się kończy, zamiast używać stałego okna czasowego trwającego pięć sekund. Jako punkt odniesienia pokazuje to, że lokalny sprzęt może przetworzyć cały łańcuch od mowy do tekstu, modelu oraz syntezy mowy w ciągu zaledwie kilku sekund.

Co umożliwia sprzęt

Lokalne modele są ograniczone przede wszystkim przepustowością pamięci, a nie samą mocą obliczeniową. To, jak szybko wagi przechodzą z pamięci RAM do jąder obliczeniowych, ma większe znaczenie niż szybkość wykonywania operacji arytmetycznych przez procesor, i to właśnie ten czynnik decyduje o tym, który model nadaje się dla danego urządzenia.

Laptop z 16 GB pamięci, bez oddzielnej karty graficznej, osiąga maksymalną przepustowość pamięci systemowej na poziomie 50 do 70 GB/s. Może uruchamiać modele qwen3:8b lub qwen2.5-coder:7b na procesorze z szybkością 8 do 12 tokenów na sekundę, co jest wystarczające do zadań związanych z wyszukiwaniem informacji i obsługą głosu, ale za wolne do kodowania. Apple Silicon odwraca tę sytuację dzięki zintegrowanej pamięci o przepustowości 200 do 400 GB/s, więc model z serii M Pro lub Max z 24 do 36 GB pamięci bez problemu obsługuje model qwen3-coder:30b, ponieważ architektura MoE aktywuje jedynie 3 miliardy parametrów na token.

Karty NVIDIA oferują większą pojemność pamięci w zamian za mniejszą przepustowość. Przy 12 do 16 GB pamięci VRAM model qwen3:8b uruchamia się natychmiast, a zkwantyzowany model qwen3-coder:30b również pasuje. Przy 24 GB lub więcej pamięci, np. w kartach RTX 3090 lub 4090, model 30B działa z pełną prędkością, co przy pracy z pojedynczym plikiem przypomina korzystanie z płatnej subskrypcji. Przy mniej niż 8 GB pamięci RAM kodowanie jest w większości niemożliwe, więc realistycznym rozwiązaniem są modele qwen3:4b lub phi-4-mini do zadań związanych z obsługą głosu i prostym wyszukiwaniem informacji.

Podobne artykuły

  • Przegrupowanie danych w RAG: Kodowniki międzywykonawcze a sprawdzacze LLM oraz ich opóźnienia — Jak narzędzie do drugiego etapu przegrupowania poprawia kolejność kandydatów w RAG, porównując kodowniki międzywykonawcze ze sprawdzaczami LLM, koszty opóźnień, możliwe błędy oraz sposoby ich oceny.
  • Szukanie wideo i audio według znaczenia: Budowa systemu RAG wielomodalnego z użyciem Gemini Embedding 2 — Jak pojedyncza przestrzeń embeddingów dla tekstu, audio, wideo i plików PDF zastąpiła procesy transkrypcji, wraz z funkcjami dzielenia na fragmenty, ChromaDB, rozszerzania zapytań, przegrupowywania danych i ustalania progów.
  • Graphify, OKF i RAG: Która warstwa kontekstowa jest potrzebna Twojemu kodowi — Testy pokazują, że Graphify dorównuje pod względem dokładności wektorowemu RAG. Oto jak Graphify, OKF od Google oraz wektorowe RAG współpracują ze sobą, wraz z czynnikami powodującymi awarie i macierzą decyzyjną.
  • Prywatny multimodalny RAG na M1 Mac: Selektywne odczytywanie wykresów za pomocą Ollamy — Szukaj poufnych plików PDF offline: PyMuPDF do tekstu i tabel, mały model wizyjny Qwen tylko do wykresów, weryfikacja numerów oraz wyszukiwanie elementów rodzicielsko-dzietnych w ChromaDB.