#
Implementarea Optimizată a Inferenței

În această secțiune, vom explora framework-uri avansate pentru optimizarea implementărilor LLM: Text Generation Inference (TGI), vLLM și llama.cpp. Aceste aplicații sunt utilizate în principal în medii de producție pentru a servi LLM-uri utilizatorilor. Această secțiune se concentrează pe modul de implementare a acestor framework-uri în producție, mai degrabă decât pe modul de utilizare pentru inferență pe o singură mașină.

Vom acoperi modul în care aceste instrumente maximizează eficiența inferenței și simplifică implementările de producție ale Modelelor de Limbaj de Mari Dimensiuni.

##
Ghid de Selecție a Framework-ului

TGI, vLLM și llama.cpp servesc scopuri similare, dar au caracteristici distincte care le fac mai potrivite pentru diferite cazuri de utilizare. Să ne uităm la diferențele cheie dintre ele, concentrându-ne pe performanță și integrare.

###
Gestionarea Memoriei și Performanța

TGI este proiectat să fie stabil și previzibil în producție, folosind lungimi fixe de secvență pentru a menține utilizarea memoriei consistentă. TGI gestionează memoria folosind Flash Attention 2 și tehnici de procesare continuă în loturi. Aceasta înseamnă că poate procesa calculele de atenție foarte eficient și poate menține GPU-ul ocupat prin alimentarea constantă cu lucru. Sistemul poate muta părți ale modelului între CPU și GPU când este necesar, ceea ce ajută la gestionarea modelelor mai mari.

Flash Attention este o tehnică care optimizează mecanismul de atenție în modelele transformer prin abordarea blocajelor de lățime de bandă a memoriei. Așa cum s-a discutat mai devreme în [Capitolul 1.8](/course/chapter1/8), mecanismul de atenție are complexitate și utilizare de memorie pătratică, făcându-l ineficient pentru secvențe lungi.

Inovația cheie constă în modul în care gestionează transferurile de memorie între High Bandwidth Memory (HBM) și cache-ul SRAM mai rapid. Atenția tradițională transferă în mod repetat date între HBM și SRAM, creând blocaje prin lăsarea GPU-ului inactiv. Flash Attention încarcă datele o dată în SRAM și efectuează toate calculele acolo, minimizând transferurile costisitoare de memorie.

Deși beneficiile sunt cele mai semnificative în timpul antrenamentului, utilizarea redusă de VRAM și eficiența îmbunătățită a Flash Attention o fac valoroasă și pentru inferență, permițând servirea LLM mai rapidă și mai scalabilă.

vLLM adoptă o abordare diferită prin utilizarea PagedAttention. La fel cum un computer își gestionează memoria în pagini, vLLM împarte memoria modelului în blocuri mai mici. Acest sistem inteligent înseamnă că poate gestiona cereri de dimensiuni diferite mai flexibil și nu risipește spațiul de memorie. Este deosebit de bun la partajarea memoriei între diferite cereri și reduce fragmentarea memoriei, ceea ce face întregul sistem mai eficient.

PagedAttention este o tehnică care abordează un alt blocaj critic în inferența LLM: gestionarea memoriei cache KV. Așa cum s-a discutat în [Capitolul 1.8](/course/chapter1/8), în timpul generării de text, modelul stochează cheile și valorile de atenție (cache KV) pentru fiecare token generat pentru a reduce calculele redundante. Cache-ul KV poate deveni enorm, în special cu secvențe lungi sau multiple cereri concurente.

Inovația cheie a vLLM constă în modul în care gestionează acest cache:

1. Paginarea Memoriei: În loc să trateze cache-ul KV ca un bloc mare, este împărțit în “pagini” de dimensiune fixă (similar cu memoria virtuală în sistemele de operare).
2. Stocare Non-Contigua: Paginile nu trebuie să fie stocate contiguu în memoria GPU, permițând o alocare mai flexibilă a memoriei.
3. Gestionarea Tabelului de Pagini: Un tabel de pagini urmărește care pagini aparțin cărei secvențe, permițând căutare și acces eficient.
4. Partajarea Memoriei: Pentru operații precum eșantionarea paralelă, paginile care stochează cache-ul KV pentru prompt pot fi partajate între multiple secvențe.

Abordarea PagedAttention poate duce la un throughput de până la 24 de ori mai mare comparativ cu metodele tradiționale, făcând-o o schimbare de paradigmă pentru implementările LLM de producție. Dacă vrei să înțelegi cu adevărat în profunzime cum funcționează PagedAttention, poți citi ghidul din documentația vLLM.

llama.cpp este o implementare C/C++ extrem de optimizată proiectată inițial pentru rularea modelelor LLaMA pe hardware de consum. Se concentrează pe eficiența CPU cu accelerație GPU opțională și este ideal pentru medii cu resurse limitate. llama.cpp folosește tehnici de cuantificare pentru a reduce dimensiunea modelului și cerințele de memorie menținând în același timp performanță bună. Implementează kerneluri optimizate pentru diverse arhitecturi CPU și suportă gestionarea de bază a cache-ului KV pentru generarea eficientă de token-uri.

Cuantificarea în llama.cpp reduce precizia ponderilor modelului de la puncte mobile pe 32-bit sau 16-bit la formate de precizie mai mică precum întregi pe 8-bit (INT8), 4-bit sau chiar mai mic. Aceasta reduce semnificativ utilizarea memoriei și îmbunătățește viteza de inferență cu pierderi minime de calitate.

Caracteristicile cheie de cuantificare în llama.cpp includ:

1. Multiple Niveluri de Cuantificare: Suportă cuantificare pe 8-bit, 4-bit, 3-bit și chiar 2-bit
2. Format GGML/GGUF: Folosește formate tensoriale personalizate optimizate pentru inferența cuantificată
3. Precizie Mixtă: Poate aplica diferite niveluri de cuantificare la diferite părți ale modelului
4. Optimizări Specifice Hardware: Include căi de cod optimizate pentru diverse arhitecturi CPU (AVX2, AVX-512, NEON)

Această abordare permite rularea modelelor cu miliarde de parametri pe hardware de consum cu memorie limitată, făcând-o perfectă pentru implementări locale și dispozitive de margine.

###
Implementarea și Integrarea

Să trecem la diferențele de implementare și integrare între framework-uri.

TGI excelează în implementarea la nivel enterprise cu caracteristicile sale gata pentru producție. Vine cu suport Kubernetes integrat și include tot ce ai nevoie pentru rularea în producție, precum monitorizarea prin Prometheus și Grafana, scalarea automată și caracteristici cuprinzătoare de siguranță. Sistemul include, de asemenea, logare de nivel enterprise și diverse măsuri de protecție precum filtrarea conținutului și limitarea ratei pentru a menține implementarea sigură și stabilă.

vLLM adoptă o abordare mai flexibilă, prietenoasă cu dezvoltatorii pentru implementare. Este construit cu Python în nucleu și poate înlocui cu ușurință API-ul OpenAI în aplicațiile tale existente. Framework-ul se concentrează pe livrarea performanței brute și poate fi personalizat pentru a se potrivi nevoilor tale specifice. Funcționează deosebit de bine cu Ray pentru gestionarea clusterelor, făcându-l o alegere excelentă când ai nevoie de performanță înaltă și adaptabilitate.

llama.cpp prioritizează simplitatea și portabilitatea. Implementarea sa de server este ușoară și poate rula pe o gamă largă de hardware, de la servere puternice la laptopuri de consum și chiar unele dispozitive mobile de înaltă performanță. Cu dependențe minime și un nucleu C/C++ simplu, este ușor de implementat în medii unde instalarea framework-urilor Python ar fi provocatoare. Serverul oferă un API compatibil cu OpenAI menținând în același timp un amprentă de resurse mult mai mică decât alte soluții.

##
Începerea

Să explorăm cum să folosim aceste framework-uri pentru implementarea LLM-urilor, începând cu instalarea și configurarea de bază.

###
Instalarea și Configurarea de Bază

<hfoption value="tgi" label="TGI">

TGI este ușor de instalat și utilizat, cu integrare profundă în ecosistemul Hugging Face.

Mai întâi, lansează serverul TGI folosind Docker:

    docker run --gpus all \
        --shm-size 1g \
        -p 8080:80 \
        -v ~/.cache/huggingface:/data \
        ghcr.io/huggingface/text-generation-inference:latest \
        --model-id HuggingFaceTB/SmolLM2-360M-Instruct

Apoi interacționează cu acesta folosind InferenceClient de la Hugging Face:

    from huggingface_hub import InferenceClient

    # Inițializează clientul pointând către endpoint-ul TGI
    client = InferenceClient(
        model="http://localhost:8080",  # URL către serverul TGI
    )

    # Generarea de text
    response = client.text_generation(
        "Spune-mi o poveste",
        max_new_tokens=100,
        temperature=0.7,
        top_p=0.95,
        details=True,
        stop_sequences=[],
    )
    print(response.generated_text)

    # Pentru format de chat
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

Alternativ, poți folosi clientul OpenAI:

    from openai import OpenAI

    # Inițializează clientul pointând către endpoint-ul TGI
    client = OpenAI(
        base_url="http://localhost:8080/v1",  # Asigură-te să incluzi /v1
        api_key="not-needed",  # TGI nu necesită o cheie API în mod implicit
    )

    # Completarea de chat
    response = client.chat.completions.create(
        model="HuggingFaceTB/SmolLM2-360M-Instruct",
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

</hfoption> <hfoption value="llama.cpp" label="llama.cpp">

llama.cpp este ușor de instalat și utilizat, necesitând dependențe minime și suportând atât inferența CPU cât și GPU.

Mai întâi, instalează și construiește llama.cpp:

    # Clonează depozitul
    git clone https://github.com/ggerganov/llama.cpp
    cd llama.cpp

    # Construiește proiectul
    make

    # Descarcă modelul SmolLM2-1.7B-Instruct-GGUF
    curl -L -O https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct-GGUF/resolve/main/smollm2-1.7b-instruct.Q4_K_M.gguf

Apoi, lansează serverul (cu compatibilitate API OpenAI):

    # Pornește serverul
    ./server \
        -m smollm2-1.7b-instruct.Q4_K_M.gguf \
        --host 0.0.0.0 \
        --port 8080 \
        -c 4096 \
        --n-gpu-layers 0  # Setează la un număr mai mare pentru a folosi GPU

Interacționează cu serverul folosind InferenceClient de la Hugging Face:

    from huggingface_hub import InferenceClient

    # Inițializează clientul pointând către serverul llama.cpp
    client = InferenceClient(
        model="http://localhost:8080/v1",  # URL către serverul llama.cpp
        token="sk-no-key-required",  # serverul llama.cpp necesită acest placeholder
    )

    # Generarea de text
    response = client.text_generation(
        "Spune-mi o poveste",
        max_new_tokens=100,
        temperature=0.7,
        top_p=0.95,
        details=True,
    )
    print(response.generated_text)

    # Pentru format de chat
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

Alternativ, poți folosi clientul OpenAI:

    from openai import OpenAI

    # Inițializează clientul pointând către serverul llama.cpp
    client = OpenAI(
        base_url="http://localhost:8080/v1",
        api_key="sk-no-key-required",  # serverul llama.cpp necesită acest placeholder
    )

    # Completarea de chat
    response = client.chat.completions.create(
        model="smollm2-1.7b-instruct",  # Identificatorul modelului poate fi orice deoarece serverul încarcă doar un model
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

</hfoption> <hfoption value="vllm" label="vLLM">

vLLM este ușor de instalat și utilizat, cu atât compatibilitatea API OpenAI cât și o interfață Python nativă.

Mai întâi, lansează serverul compatibil OpenAI vLLM:

    python -m vllm.entrypoints.openai.api_server \
        --model HuggingFaceTB/SmolLM2-360M-Instruct \
        --host 0.0.0.0 \
        --port 8000

Apoi interacționează cu acesta folosind InferenceClient de la Hugging Face:

    from huggingface_hub import InferenceClient

    # Inițializează clientul pointând către endpoint-ul vLLM
    client = InferenceClient(
        model="http://localhost:8000/v1",  # URL către serverul vLLM
    )

    # Generarea de text
    response = client.text_generation(
        "Spune-mi o poveste",
        max_new_tokens=100,
        temperature=0.7,
        top_p=0.95,
        details=True,
    )
    print(response.generated_text)

    # Pentru format de chat
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

Alternativ, poți folosi clientul OpenAI:

    from openai import OpenAI

    # Inițializează clientul pointând către endpoint-ul vLLM
    client = OpenAI(
        base_url="http://localhost:8000/v1",
        api_key="not-needed",  # vLLM nu necesită o cheie API în mod implicit
    )

    # Completarea de chat
    response = client.chat.completions.create(
        model="HuggingFaceTB/SmolLM2-360M-Instruct",
        messages=[
            {"role": "system", "content": "Ești un asistent util."},
            {"role": "user", "content": "Spune-mi o poveste"},
        ],
        max_tokens=100,
        temperature=0.7,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

</hfoption>

###
Generarea de Bază a Textului

Să ne uităm la exemple de generare de text cu framework-urile:

<hfoption value="tgi" label="TGI">

Mai întâi, implementează TGI cu parametri avansați:

    docker run --gpus all \
        --shm-size 1g \
        -p 8080:80 \
        -v ~/.cache/huggingface:/data \
        ghcr.io/huggingface/text-generation-inference:latest \
        --model-id HuggingFaceTB/SmolLM2-360M-Instruct \
        --max-total-tokens 4096 \
        --max-input-length 3072 \
        --max-batch-total-tokens 8192 \
        --waiting-served-ratio 1.2

Folosește InferenceClient pentru generarea flexibilă de text:

    from huggingface_hub import InferenceClient

    client = InferenceClient(model="http://localhost:8080")

    # Exemplu de parametri avansați
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,
        max_tokens=200,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

    # Generarea brută de text
    response = client.text_generation(
        "Scrie o poveste creativă despre explorarea spațiului",
        max_new_tokens=200,
        temperature=0.8,
        top_p=0.95,
        repetition_penalty=1.1,
        do_sample=True,
        details=True,
    )
    print(response.generated_text)

Sau folosește clientul OpenAI:

    from openai import OpenAI

    client = OpenAI(base_url="http://localhost:8080/v1", api_key="not-needed")

    # Exemplu de parametri avansați
    response = client.chat.completions.create(
        model="HuggingFaceTB/SmolLM2-360M-Instruct",
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,  # Mai mare pentru mai multă creativitate
    )
    print(response.choices[0].message.content)

</hfoption> <hfoption value="llama.cpp" label="llama.cpp">

Pentru llama.cpp, poți seta parametri avansați când lansezi serverul:

    ./server \
        -m smollm2-1.7b-instruct.Q4_K_M.gguf \
        --host 0.0.0.0 \
        --port 8080 \
        -c 4096 \            # Dimensiunea contextului
        --threads 8 \        # Thread-uri CPU de folosit
        --batch-size 512 \   # Dimensiunea lotului pentru evaluarea prompt-ului
        --n-gpu-layers 0     # Straturi GPU (0 = doar CPU)

Folosește InferenceClient:

    from huggingface_hub import InferenceClient

    client = InferenceClient(model="http://localhost:8080/v1", token="sk-no-key-required")

    # Exemplu de parametri avansați
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,
        max_tokens=200,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

    # Pentru generarea directă de text
    response = client.text_generation(
        "Scrie o poveste creativă despre explorarea spațiului",
        max_new_tokens=200,
        temperature=0.8,
        top_p=0.95,
        repetition_penalty=1.1,
        details=True,
    )
    print(response.generated_text)

Sau folosește clientul OpenAI pentru generare cu control asupra parametrilor de eșantionare:

    from openai import OpenAI

    client = OpenAI(base_url="http://localhost:8080/v1", api_key="sk-no-key-required")

    # Exemplu de parametri avansați
    response = client.chat.completions.create(
        model="smollm2-1.7b-instruct",
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,  # Mai mare pentru mai multă creativitate
        top_p=0.95,  # Probabilitatea eșantionării nucleus
        frequency_penalty=0.5,  # Reduce repetarea token-urilor frecvente
        presence_penalty=0.5,  # Reduce repetarea prin penalizarea token-urilor deja prezente
        max_tokens=200,  # Lungimea maximă de generare
    )
    print(response.choices[0].message.content)

Poți folosi, de asemenea, biblioteca nativă llama.cpp pentru un control și mai mare:

    # Folosind pachetul llama-cpp-python pentru accesul direct la model
    from llama_cpp import Llama

    # Încarcă modelul
    llm = Llama(
        model_path="smollm2-1.7b-instruct.Q4_K_M.gguf",
        n_ctx=4096,  # Dimensiunea ferestrei de context
        n_threads=8,  # Thread-uri CPU
        n_gpu_layers=0,  # Straturi GPU (0 = doar CPU)
    )

    # Formatează prompt-ul conform formatului așteptat al modelului
    prompt = """<|im_start|>system
    Ești un povestitor creativ.
    <|im_end|>
    <|im_start|>user
    Scrie o poveste creativă
    <|im_end|>
    <|im_start|>assistant
    """

    # Generează răspunsul cu control precis al parametrilor
    output = llm(
        prompt,
        max_tokens=200,
        temperature=0.8,
        top_p=0.95,
        frequency_penalty=0.5,
        presence_penalty=0.5,
        stop=["<|im_end|>"],
    )

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

</hfoption> <hfoption value="vllm" label="vLLM">

Pentru utilizarea avansată cu vLLM, poți folosi InferenceClient:

    from huggingface_hub import InferenceClient

    client = InferenceClient(model="http://localhost:8000/v1")

    # Exemplu de parametri avansați
    response = client.chat_completion(
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,
        max_tokens=200,
        top_p=0.95,
    )
    print(response.choices[0].message.content)

    # Pentru generarea directă de text
    response = client.text_generation(
        "Scrie o poveste creativă despre explorarea spațiului",
        max_new_tokens=200,
        temperature=0.8,
        top_p=0.95,
        details=True,
    )
    print(response.generated_text)

Poți folosi, de asemenea, clientul OpenAI:

    from openai import OpenAI

    client = OpenAI(base_url="http://localhost:8000/v1", api_key="not-needed")

    # Exemplu de parametri avansați
    response = client.chat.completions.create(
        model="HuggingFaceTB/SmolLM2-360M-Instruct",
        messages=[
            {"role": "system", "content": "Ești un povestitor creativ."},
            {"role": "user", "content": "Scrie o poveste creativă"},
        ],
        temperature=0.8,
        top_p=0.95,
        max_tokens=200,
    )
    print(response.choices[0].message.content)

vLLM oferă, de asemenea, o interfață Python nativă cu control fin:

    from vllm import LLM, SamplingParams

    # Inițializează modelul cu parametri avansați
    llm = LLM(
        model="HuggingFaceTB/SmolLM2-360M-Instruct",
        gpu_memory_utilization=0.85,
        max_num_batched_tokens=8192,
        max_num_seqs=256,
        block_size=16,
    )

    # Configurează parametrii de eșantionare
    sampling_params = SamplingParams(
        temperature=0.8,  # Mai mare pentru mai multă creativitate
        top_p=0.95,  # Consideră masa de probabilitate de top 95%
        max_tokens=100,  # Lungimea maximă
        presence_penalty=1.1,  # Reduce repetarea
        frequency_penalty=1.1,  # Reduce repetarea
        stop=["\n\n", "###"],  # Secvențe de oprire
    )

    # Generează text
    prompt = "Scrie o poveste creativă"
    outputs = llm.generate(prompt, sampling_params)
    print(outputs[0].outputs[0].text)

    # Pentru interacțiuni în stil chat
    chat_prompt = [
        {"role": "system", "content": "Ești un povestitor creativ."},
        {"role": "user", "content": "Scrie o poveste creativă"},
    ]
    formatted_prompt = llm.get_chat_template()(
        chat_prompt
    )  # Folosește șablonul de chat al modelului
    outputs = llm.generate(formatted_prompt, sampling_params)
    print(outputs[0].outputs[0].text)

</hfoption>

##
Controlul Avansat al Generării

###
Selecția Token-urilor și Eșantionarea

Procesul de generare a textului implică selectarea următorului token la fiecare pas. Acest proces de selecție poate fi controlat prin diverși parametri:

1. Logit-uri Brute: Probabilitățile inițiale de ieșire pentru fiecare token
2. Temperatura: Controlează aleatoriul în selecție (mai mare = mai creativ)
3. Eșantionarea Top-p (Nucleus): Filtrează la token-urile de top care alcătuiesc X% din masa de probabilitate
4. Filtrarea Top-k: Limitează selecția la k token-uri cele mai probabile

Iată cum să configurezi acești parametri:

<hfoption value="tgi" label="TGI">

    client.generate(
        "Scrie o poveste creativă",
        temperature=0.8,  # Mai mare pentru mai multă creativitate
        top_p=0.95,  # Consideră masa de probabilitate de top 95%
        top_k=50,  # Consideră top 50 de token-uri
        max_new_tokens=100,  # Lungimea maximă
        repetition_penalty=1.1,  # Reduce repetarea
    )

</hfoption> <hfoption value="llama.cpp" label="llama.cpp">

    # Prin compatibilitatea API OpenAI
    response = client.completions.create(
        model="smollm2-1.7b-instruct",  # Numele modelului (poate fi orice string pentru serverul llama.cpp)
        prompt="Scrie o poveste creativă",
        temperature=0.8,  # Mai mare pentru mai multă creativitate
        top_p=0.95,  # Consideră masa de probabilitate de top 95%
        frequency_penalty=1.1,  # Reduce repetarea
        presence_penalty=0.1,  # Reduce repetarea
        max_tokens=100,  # Lungimea maximă
    )

    # Prin accesul direct llama-cpp-python
    output = llm(
        "Scrie o poveste creativă",
        temperature=0.8,
        top_p=0.95,
        top_k=50,
        max_tokens=100,
        repeat_penalty=1.1,
    )

</hfoption> <hfoption value="vllm" label="vLLM">

    params = SamplingParams(
        temperature=0.8,  # Mai mare pentru mai multă creativitate
        top_p=0.95,  # Consideră masa de probabilitate de top 95%
        top_k=50,  # Consideră top 50 de token-uri
        max_tokens=100,  # Lungimea maximă
        presence_penalty=0.1,  # Reduce repetarea
    )
    llm.generate("Scrie o poveste creativă", sampling_params=params)

</hfoption>

###
Controlul Repetării

Ambele framework-uri oferă modalități de a preveni generarea repetitivă de text:

<hfoption value="tgi" label="TGI"> ```python client.generate( "Scrie un text variat", repetition_penalty=1.1, # Penalizează token-urile repetate no_repeat_ngram_size=3, # Previne repetarea de 3-grame ) ``` </hfoption> <hfoption value="llama.cpp" label="llama.cpp">

    # Prin API OpenAI
    response = client.completions.create(
        model="smollm2-1.7b-instruct",
        prompt="Scrie un text variat",
        frequency_penalty=1.1,  # Penalizează token-urile frecvente
        presence_penalty=0.8,  # Penalizează token-urile deja prezente
    )

    # Prin biblioteca directă
    output = llm(
        "Scrie un text variat",
        repeat_penalty=1.1,  # Penalizează token-urile repetate
        frequency_penalty=0.5,  # Penalitate de frecvență adițională
        presence_penalty=0.5,  # Penalitate de prezență adițională
    )

</hfoption> <hfoption value="vllm" label="vLLM">

    params = SamplingParams(
        presence_penalty=0.1,  # Penalizează prezența token-urilor
        frequency_penalty=0.1,  # Penalizează frecvența token-urilor
    )

</hfoption>

###
Controlul Lungimii și Secvențele de Oprire

Poți controla lungimea generării și specifica când să se oprească:

<hfoption value="tgi" label="TGI"> ```python client.generate( "Generează un paragraf scurt", max_new_tokens=100, min_new_tokens=10, stop_sequences=["\n\n", "###"], ) ``` </hfoption> <hfoption value="llama.cpp" label="llama.cpp">

    # Prin API OpenAI
    response = client.completions.create(
        model="smollm2-1.7b-instruct",
        prompt="Generează un paragraf scurt",
        max_tokens=100,
        stop=["\n\n", "###"],
    )

    # Prin biblioteca directă
    output = llm("Generează un paragraf scurt", max_tokens=100, stop=["\n\n", "###"])

</hfoption> <hfoption value="vllm" label="vLLM">

    params = SamplingParams(
        max_tokens=100,
        min_tokens=10,
        stop=["###", "\n\n"],
        ignore_eos=False,
        skip_special_tokens=True,
    )

</hfoption>

##
Gestionarea Memoriei

Ambele framework-uri implementează tehnici avansate de gestionare a memoriei pentru inferența eficientă.

<hfoption value="tgi" label="TGI"> TGI folosește Flash Attention 2 și procesarea continuă în loturi:

    # Implementarea Docker cu optimizarea memoriei
    docker run --gpus all -p 8080:80 \
        --shm-size 1g \
        ghcr.io/huggingface/text-generation-inference:latest \
        --model-id HuggingFaceTB/SmolLM2-1.7B-Instruct \
        --max-batch-total-tokens 8192 \
        --max-input-length 4096

</hfoption> <hfoption value="llama.cpp" label="llama.cpp">

llama.cpp folosește cuantificarea și dispunerea optimată a memoriei:

    # Server cu optimizări de memorie
    ./server \
        -m smollm2-1.7b-instruct.Q4_K_M.gguf \
        --host 0.0.0.0 \
        --port 8080 \
        -c 2048 \               # Dimensiunea contextului
        --threads 4 \           # Thread-uri CPU
        --n-gpu-layers 32 \     # Folosește mai multe straturi GPU pentru modele mai mari
        --mlock \               # Blochează memoria pentru a preveni swapping-ul
        --cont-batching         # Activează procesarea continuă în loturi

Pentru modele prea mari pentru GPU-ul tău, poți folosi offloading-ul CPU:

    ./server \
        -m smollm2-1.7b-instruct.Q4_K_M.gguf \
        --n-gpu-layers 20 \     # Păstrează primele 20 de straturi pe GPU
        --threads 8             # Folosește mai multe thread-uri CPU pentru straturile CPU

</hfoption> <hfoption value="vllm" label="vLLM">

vLLM folosește PagedAttention pentru gestionarea optimă a memoriei:

    from vllm.engine.arg_utils import AsyncEngineArgs

    engine_args = AsyncEngineArgs(
        model="HuggingFaceTB/SmolLM2-1.7B-Instruct",
        gpu_memory_utilization=0.85,
        max_num_batched_tokens=8192,
        block_size=16,
    )

    llm = LLM(engine_args=engine_args)

</hfoption>

##
Resurse

- Documentația Text Generation Inference
- Depozitul GitHub TGI
- Documentația vLLM
- Depozitul GitHub vLLM
- Lucrarea PagedAttention
- Depozitul GitHub llama.cpp
- Depozitul llama-cpp-python

< > Update on GitHub