| import gradio as gr |
| from llama_cpp import Llama |
| from huggingface_hub import hf_hub_download |
| from pathlib import Path |
| import base64 |
|
|
| |
| |
| |
|
|
| MODEL_REPO_ID = "FPll/MIND-GGUF" |
| GGUF_FILENAME = "Meta-Llama-3.1-8B-Instruct.Q4_K_M.gguf" |
|
|
| print("Download modello GGUF da Hugging Face...") |
|
|
| model_path = hf_hub_download( |
| repo_id=MODEL_REPO_ID, |
| filename=GGUF_FILENAME, |
| repo_type="model", |
| ) |
|
|
| print("Modello scaricato:", model_path) |
|
|
| llm = Llama( |
| model_path=model_path, |
| n_ctx=4096, |
| n_threads=2, |
| n_gpu_layers=0, |
| chat_format="llama-3", |
| verbose=False, |
| ) |
|
|
| |
| |
| |
|
|
| SYSTEM_PROMPT = """Rispondi come MIND, mentor Python creato nel contesto del Progetto MIND e del percorso IFTS MIND – Machine Intelligence & Data di Formatica S.c.a.r.l., Agenzia di Formazione. |
| |
| La tua funzione è stata definita dal docente Francesco Palladino insieme agli studenti Matteo Ciorra, Luca Lombardo, Nicola Boi e Leonardo Isoni per guidare l'apprendimento del codice. |
| |
| Regole di comportamento: |
| - Rispondi sempre in italiano. |
| - Se l'utente chiede chi sei, rispondi in prima persona: "Sono MIND...". |
| - Mantieni un tono chiaro, tecnico, incoraggiante e paziente. |
| - Quando dai codice Python, usa blocchi Markdown ben formattati. |
| - Se l'utente chiede un esercizio su un argomento specifico, rispetta esattamente l'argomento richiesto. |
| - Se l'utente chiede un esercizio sui cicli for, usa un ciclo for, non un ciclo while. |
| - Quando proponi esercizi semplici sui cicli for con numeri consecutivi, preferisci `range()` invece di creare manualmente una lista. |
| - Se l'utente chiede la soluzione a un esercizio, guida prima nel ragionamento e poi offri un esempio di codice commentato. |
| """ |
|
|
| |
| |
| |
|
|
| def chat_con_mind(messaggio, cronologia): |
| messages = [ |
| {"role": "system", "content": SYSTEM_PROMPT} |
| ] |
|
|
| for utente, assistente in cronologia: |
| if utente: |
| messages.append({"role": "user", "content": utente}) |
| if assistente: |
| messages.append({"role": "assistant", "content": assistente}) |
|
|
| messages.append({"role": "user", "content": messaggio}) |
|
|
| output = llm.create_chat_completion( |
| messages=messages, |
| max_tokens=1024, |
| temperature=0.4, |
| top_p=0.9, |
| repeat_penalty=1.15, |
| stop=[ |
| "<|eot_id|>", |
| "<|start_header_id|>user<|end_header_id|>", |
| "<|start_header_id|>system<|end_header_id|>", |
| ], |
| ) |
|
|
| risposta = output["choices"][0]["message"]["content"].strip() |
|
|
| prefissi_da_rimuovere = [ |
| "assistant\n", |
| "assistant:", |
| ".assistant", |
| "<|start_header_id|>assistant<|end_header_id|>", |
| ] |
|
|
| for prefisso in prefissi_da_rimuovere: |
| if risposta.startswith(prefisso): |
| risposta = risposta[len(prefisso):].strip() |
|
|
| return risposta |
|
|
| |
| |
| |
|
|
| ICON_PATH = Path("mind_icon.png") |
|
|
| def crea_header_html(): |
| if ICON_PATH.exists(): |
| icon_base64 = base64.b64encode(ICON_PATH.read_bytes()).decode("utf-8") |
| icon_html = ( |
| '<img class="mind-logo" ' |
| f'src="data:image/png;base64,{icon_base64}" ' |
| 'alt="MIND logo">' |
| ) |
| else: |
| icon_html = '<span class="mind-emoji">🤖</span>' |
|
|
| return ( |
| '<div class="mind-header">' |
| f'{icon_html}' |
| '<div>' |
| '<h1>MIND - Mentor Python</h1>' |
| '<p>Progetto IFTS MIND - Machine Intelligence & Data di Formatica S.c.a.r.l.</p>' |
| '</div>' |
| '</div>' |
| ) |
|
|
| custom_css = ''' |
| .mind-header { |
| display: flex; |
| align-items: center; |
| gap: 16px; |
| margin-bottom: 18px; |
| } |
| |
| .mind-header h1 { |
| margin: 0; |
| font-size: 2rem; |
| } |
| |
| .mind-header p { |
| margin: 4px 0 0 0; |
| opacity: 0.75; |
| } |
| |
| .mind-logo { |
| width: 64px; |
| height: 64px; |
| animation: mindHue 4s linear infinite; |
| } |
| |
| .mind-emoji { |
| font-size: 56px; |
| animation: mindHue 4s linear infinite; |
| } |
| |
| @keyframes mindHue { |
| 0% { |
| filter: hue-rotate(0deg) drop-shadow(0 0 4px rgba(0, 90, 255, 0.5)); |
| } |
| 50% { |
| filter: hue-rotate(160deg) drop-shadow(0 0 8px rgba(120, 0, 255, 0.7)); |
| } |
| 100% { |
| filter: hue-rotate(360deg) drop-shadow(0 0 4px rgba(0, 90, 255, 0.5)); |
| } |
| } |
| ''' |
|
|
| |
| |
| |
|
|
| with gr.Blocks(css=custom_css) as interfaccia: |
| gr.HTML(crea_header_html()) |
|
|
| gr.ChatInterface( |
| fn=chat_con_mind, |
| title=None, |
| description="Scrivi una domanda su Python, esercizi, debugging, funzioni, cicli, NumPy, Matplotlib o piccoli progetti." |
| ) |
|
|
| if __name__ == "__main__": |
| interfaccia.launch() |