-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.py
More file actions
99 lines (80 loc) · 3.59 KB
/
Copy pathtest.py
File metadata and controls
99 lines (80 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import torch
# Patch temporanea per PyTorch < 2.6
for i in range(1, 8):
if not hasattr(torch, f'int{i}'):
setattr(torch, f'int{i}', torch.int8)
from unsloth import FastLanguageModel
max_seq_length = 2048
# Domande di test che coprono tutti gli scenari del dataset aziendale
domande_test = [
# Dal dataset originale
"Inizializza il logger aziendale per registrare un errore critico nel modulo pagamenti.",
"Scrivi la connessione al database Read-Only utilizzando il wrapper interno.",
"Come dobbiamo recuperare i segreti in produzione?",
"Genera il Dockerfile standard per un servizio Node.js interno.",
"Scrivi una query SQLAlchemy per recuperare gli utenti attivi, usando il soft-delete aziendale.",
# Domande nuove ma inerenti ai pattern aziendali appresi
"Crea un componente React per un bottone di invio secondo il nostro Design System (NexusUI).",
"Imposta un test unitario Pytest per una rotta FastAPI usando il nostro client mockato.",
"Formatta questa risposta API secondo lo standard v3 dell'azienda.",
]
alpaca_prompt = """Di seguito è riportata un'istruzione che descrive un task aziendale, accompagnata da un input che fornisce ulteriore contesto. Scrivi una risposta che completi adeguatamente la richiesta.
### Istruzione:
{}
### Input:
{}
### Risposta:
{}"""
def genera_risposta(modello_corrente, tokenizer_corrente, domanda):
"""Genera una singola risposta dal modello per una domanda data."""
inputs = tokenizer_corrente(
[alpaca_prompt.format(domanda, "", "")],
return_tensors="pt"
).to("cuda")
outputs = modello_corrente.generate(**inputs, max_new_tokens=256, use_cache=True)
risposta = tokenizer_corrente.batch_decode(outputs, skip_special_tokens=True)[0]
# Estrae solo la parte generata dopo "### Risposta:"
return risposta.split("### Risposta:\n")[-1].strip()
# =================================================================
# FASE 1: CARICAMENTO MODELLO BASE
# =================================================================
print(">>> CARICAMENTO MODELLO BASE (VERGINE) <<<")
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen2.5-Coder-7B-Instruct",
max_seq_length=max_seq_length,
dtype=None,
load_in_4bit=True,
)
# Genera risposte dal modello base
FastLanguageModel.for_inference(model)
risposte_base = []
for domanda in domande_test:
risposte_base.append(genera_risposta(model, tokenizer, domanda))
# =================================================================
# FASE 2: CARICAMENTO ADAPTER LORA AZIENDALI
# =================================================================
print("\n>>> INIEZIONE DEGLI ADAPTER LORA AZIENDALI... <<<")
model.load_adapter("qwen-modello-aziendale")
FastLanguageModel.for_inference(model)
risposte_ft = []
for domanda in domande_test:
risposte_ft.append(genera_risposta(model, tokenizer, domanda))
# =================================================================
# FASE 3: CONFRONTO AFFIANCATO
# =================================================================
print("\n" + "=" * 80)
print(" CONFRONTO: MODELLO BASE vs MODELLO FINE-TUNED")
print("=" * 80)
for i, domanda in enumerate(domande_test):
print(f"\n{'─' * 80}")
print(f" DOMANDA {i+1}: {domanda}")
print(f"{'─' * 80}")
print(f"\n 📦 MODELLO BASE:")
for line in risposte_base[i].split("\n"):
print(f" {line}")
print(f"\n 🎯 MODELLO FINE-TUNED:")
for line in risposte_ft[i].split("\n"):
print(f" {line}")
print(f"\n{'=' * 80}")
print(f" Test completato: {len(domande_test)} domande confrontate.")
print(f"{'=' * 80}")