PicoDAC / README.md
Mattimax's picture
Update README.md
b690bbc verified
---
license: gpl-3.0
datasets:
- Mattimax/Little_ITA_60k
language:
- it
library_name: transformers
tags:
- DAC
- data-ai
- DATA-AI
- transformer
- experimental
new_version: Mattimax/PicoDAC-IT
---
# PicoDAC
![Logo di PicoDAC](https://huggingface.co/Mattimax/PicoDAC/resolve/main/PicoDAC_Logo/PicoDAC_Logo.png)
## Informazioni sul modello
- **Autore:** [Mattimax](https://huggingface.co/Mattimax)
- **Organizzazione:** [M.INC](https://huggingface.co/MINC01)
- **Pagina GitHub:** [PicoDAC](https://github.com/M-INC-01/PicoDAC/tree/main)
- **Licenza:** GPL-3.0
**Descrizione:**
PicoDAC è un modello di linguaggio compatto progettato per chat in lingua italiana. Basato su una architettura Transformer leggera, è ottimizzato per essere rapido e facilmente distribuibile. Questo modello è un **esperimento** ed è ancora in fase di sviluppo, quindi le prestazioni possono essere limitate rispetto a modelli più grandi e sofisticati.
**Dataset di addestramento:**
Il modello è stato addestrato sul dataset [Little_ITA_60k](https://huggingface.co/datasets/Mattimax/Little_ITA_60k), contenente conversazioni brevi in italiano.
**Obiettivo:**
Fornire un prototipo di chatbot italiano leggero, utile per test, sperimentazioni e applicazioni dove la dimensione del modello e la velocità sono prioritarie rispetto alla qualità generativa.
---
## Caratteristiche tecniche
* Architettura: Transformer autoregressivo compatto
* Dimensione del vocabolario: 1.920 token
* Lunghezza massima del contesto: 64 token
* Numero di strati (layers): 6
* Numero di teste di attenzione: 6
* Dimensione embedding: 240
* Quantizzazione: int8 per la maggior parte dei pesi, con embedding e layernorm ottimizzati a bit più alti
---
## Avvertenze e limitazioni
* Questo modello è **ancora sperimentale**: può generare risposte incoerenti o incomplete.
* Non è addestrato per conversazioni sensibili o contenuti critici.
* Performance su testi lunghi o conversazioni complesse sono limitate a causa della breve lunghezza del contesto e della piccola dimensione del modello.
---
## Uso previsto
* Chatbot sperimentali in italiano
* Applicazioni leggere dove la dimensione del modello è critica
* Prototipazione e testing di modelli di dialogo
**Nota:** consigliato l’uso con input brevi e contesti semplici.
---
## Installazione
```bash
pip install transformers torch
```
---
## Esempio di utilizzo in Python
```python
import torch
import torch.nn as nn
import torch.nn.functional as F
from huggingface_hub import hf_hub_download
from safetensors.torch import load_file
from transformers import PreTrainedTokenizerFast
import os
# ----------------------------
# Config modello
# ----------------------------
VOCAB_SIZE = 1920
D_MODEL = 240
N_LAYERS = 6
N_HEADS = 6
D_HEAD = 40
D_FF = 960
N_CTX = 64
device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Usando device: {device}")
# ----------------------------
# Scarica tokenizer e modello da HF
# ----------------------------
repo_id = "Mattimax/PicoDAC"
tokenizer_path = hf_hub_download(repo_id, "tokenizer.json")
model_path = hf_hub_download(repo_id, "model.safetensors")
# opzionale: scales_path = hf_hub_download(repo_id, "best/scales.json")
# ----------------------------
# Carica tokenizer
# ----------------------------
tokenizer = PreTrainedTokenizerFast(tokenizer_file=tokenizer_path)
tokenizer.add_special_tokens({
"pad_token": "<PAD>",
"bos_token": "<BOS>",
"eos_token": "<EOS>",
"sep_token": "<SEP>",
"unk_token": "<UNK>"
})
# ----------------------------
# RMSNorm
# ----------------------------
class RMSNorm(nn.Module):
def __init__(self, dim, eps=1e-8):
super().__init__()
self.eps = eps
self.weight = nn.Parameter(torch.ones(dim))
def forward(self, x):
norm = x.pow(2).mean(-1, keepdim=True).add(self.eps).sqrt()
return x / norm * self.weight
# ----------------------------
# Transformer Block
# ----------------------------
class TransformerBlock(nn.Module):
def __init__(self):
super().__init__()
self.ln1 = RMSNorm(D_MODEL)
self.ln2 = RMSNorm(D_MODEL)
self.attn = nn.MultiheadAttention(D_MODEL, N_HEADS, batch_first=True)
self.ffn = nn.Sequential(
nn.Linear(D_MODEL, D_FF),
nn.SiLU(),
nn.Linear(D_FF, D_MODEL)
)
def forward(self, x, mask=None):
attn_out, _ = self.attn(self.ln1(x), self.ln1(x), self.ln1(x), attn_mask=mask)
x = x + attn_out
x = x + self.ffn(self.ln2(x))
return x
# ----------------------------
# TinyGPT
# ----------------------------
class TinyGPT(nn.Module):
def __init__(self):
super().__init__()
self.tok_emb = nn.Embedding(VOCAB_SIZE, D_MODEL)
self.pos_emb = nn.Embedding(N_CTX, D_MODEL)
self.layers = nn.ModuleList([TransformerBlock() for _ in range(N_LAYERS)])
self.ln_f = RMSNorm(D_MODEL)
self.head = nn.Linear(D_MODEL, VOCAB_SIZE, bias=False)
self.head.weight = self.tok_emb.weight
def forward(self, idx):
B, T = idx.shape
pos = torch.arange(T, device=idx.device).unsqueeze(0)
x = self.tok_emb(idx) + self.pos_emb(pos)
mask = torch.triu(torch.ones(T, T, device=idx.device) * float('-inf'), diagonal=1)
for layer in self.layers:
x = layer(x, mask=mask)
x = self.ln_f(x)
logits = self.head(x)
return logits
# ----------------------------
# Carica pesi
# ----------------------------
state_dict = load_file(model_path)
model = TinyGPT()
model.load_state_dict(state_dict, strict=False)
model.to(device)
model.eval()
# ----------------------------
# Funzione generazione
# ----------------------------
def generate(prompt, max_new_tokens=50, temperature=0.7):
model_input = tokenizer.encode(prompt, return_tensors="pt").to(device)
for _ in range(max_new_tokens):
logits = model(model_input)
next_token_logits = logits[0, -1, :] / temperature
probs = F.softmax(next_token_logits, dim=-1)
next_token = torch.multinomial(probs, num_samples=1)
model_input = torch.cat([model_input, next_token.unsqueeze(0)], dim=1)
if next_token.item() == tokenizer.eos_token_id:
break
return tokenizer.decode(model_input[0], skip_special_tokens=True)
# ----------------------------
# Loop chat
# ----------------------------
print("Chat PicoDAC (scrivi 'exit' per uscire)")
while True:
user_input = input("Tu: ").strip()
if user_input.lower() in ["exit", "quit"]:
print("Chiusura chat. Ciao!")
break
response = generate(user_input)
print(f"PicoDAC: {response}")
```
**Suggerimenti pratici:**
* Usa `max_length` basso per mantenere la coerenza delle risposte.
* Temperature intorno a 0.7–1.0 favoriscono generazioni più creative.
* Evita input troppo lunghi (oltre 64 token), perché il modello può perdere il contesto precedente.
---
## Integrazione consigliata
* **Applicazioni mobile**: dimensione ridotta e quantizzazione riducono il consumo di RAM e storage.
* **Sperimentazione NLP**: utile per test di prompt, fine-tuning leggero o per costruire dataset sintetici.
---
## Riferimenti
* Dataset: [Little_ITA_60k](https://huggingface.co/datasets/Mattimax/Little_ITA_60k)
* Autore: [Mattimax](https://huggingface.co/Mattimax)
* Organizzazione: [M.INC](https://huggingface.co/MINC01)