Salvarea și încărcarea programelor DSPy pentru producție în DSPy & Programare Algoritmică LLM

Deployment și Producție Nivel: intermediar

Starea unui program optimizat (instrucțiuni, demonstrații, semnături) se salvează în JSON și se încarcă într-un program construit la fel; cu save_program=True se salvează tot programul, prin cloudpickle.

Sintaxă & invocare
program.save("program.json")
program.load("program.json")
program.save("program_dir/", save_program=True)
dspy.load("program_dir/", allow_pickle=True)

Optimizarea este scumpă, iar rezultatul ei este un artefact portabil. Fluxul din documentație este: compilezi o dată pentru o versiune a programului, salvezi, iar în producție doar încarci. Sunt două moduri. Doar starea: program.save("program.json") scrie, pentru fiecare predictor, demonstrațiile, instrucțiunile și descrierile câmpurilor, plus versiunile Python, DSPy și cloudpickle. Fișierul JSON este mic, lizibil și ușor de comparat în git. Pentru a-l folosi, construiești programul la fel ca la salvare și apelezi program.load("program.json").

Programul întreg: program.save("dir/", save_program=True) scrie în director program.pkl (cloudpickle) și metadata.json; se încarcă cu dspy.load("dir/", allow_pickle=True), fără să ai clasa programului în cod. Fără allow_pickle=True, dspy.load ridică ValueError, pentru că încărcarea unui pickle poate executa cod arbitrar. Tot pickle (.pkl în loc de .json) se folosește când starea conține obiecte care nu se pot scrie în JSON, ca dspy.Image.

Cheile API nu se salvează niciodată. Un predictor salvează configurația modelului doar dacă are un LM propriu; la încărcare, api_base, base_url și model_list sunt eliminate, cu excepția cazului allow_unsafe_lm_state=True. Configurează deci modelul la pornirea aplicației. O diferență de versiune DSPy între salvare și încărcare produce doar un avertisment.

Concepte cheie și caracteristici

Concept / Parametru Descriere practică
save(path, save_program=False, modules_to_serialize=None) .json sau .pkl: doar starea. Cu save_program=True, path este un director.
load(path, allow_pickle=False, allow_unsafe_lm_state=False) Încarcă starea într-un program existent; pentru .pkl cere allow_pickle=True.
dspy.load(path, allow_pickle=False) Încarcă un program salvat cu save_program=True; cere allow_pickle=True.
modules_to_serialize Module Python ale căror clase se includ prin valoare în pickle, când procesul care încarcă nu le poate importa.
allow_unsafe_lm_state Păstrează api_base, base_url și model_list din starea salvată.
dump_state() / load_state() Dicționarul de stare din spatele save / load.

Exemple practice și scenarii reale

Exemplul 1: Salvarea după optimizare

optimizat = optimizator.compile(program, trainset=train)
optimizat.save("artefacte/asistent_suport_v1.json")

Exemplul 2: Încărcarea într-o aplicație FastAPI

După tutorialul de deployment: programul se încarcă o singură dată, la pornire, iar dspy.asyncify îl rulează în fire separate.

from fastapi import FastAPI
from pydantic import BaseModel
import dspy

dspy.configure(lm=dspy.LM("openai/gpt-6-luna"), async_max_workers=4)

asistent = dspy.ChainOfThought("intrebare_client -> solutie_tehnica")
asistent.load("artefacte/asistent_suport_v1.json")
asistent_async = dspy.asyncify(asistent)

app = FastAPI()

class Cerere(BaseModel):
    intrebare: str

@app.post("/asistenta")
async def raspunde(cerere: Cerere):
    rez = await asistent_async(intrebare_client=cerere.intrebare)
    return {"raspuns": rez.solutie_tehnica}

Exemplul 3: Programul întreg, fără clasa lui în codul care încarcă

optimizat.save("artefacte/asistent_v1/", save_program=True)

# în alt proces
import dspy
dspy.configure(lm=dspy.LM("openai/gpt-6-luna"))
asistent = dspy.load("artefacte/asistent_v1/", allow_pickle=True)

Greșeli frecvente și capcane

  • Încarci un JSON într-un program construit altfel (alte module sau alte câmpuri decât la salvare). Construiește programul exact ca înainte de save.
  • Încarci .pkl sau un director save_program=True dintr-o sursă necunoscută. Pickle poate executa cod; preferă JSON-ul.
  • Te bazezi pe modelul salvat în fișier. Cheile API nu se salvează, iar adresele de server sunt eliminate implicit; configurează LM-ul la pornire.
  • Compilezi programul la fiecare cerere HTTP sau la fiecare pornire. Compilarea se face offline; serverul doar încarcă fișierul.

Noțiuni și module înrudite