|
import gradio as gr |
|
import json |
|
import bcrypt |
|
import os |
|
from huggingface_hub import HfApi |
|
import whisper |
|
import torch |
|
from transformers import AutoTokenizer, AutoModelForCausalLM |
|
from datetime import datetime |
|
|
|
|
|
REPO_ID = "dit-brugernavn/brugere-db" |
|
HF_TOKEN = os.getenv("HF_TOKEN") |
|
|
|
BRUGERE_FIL = "brugere.json" |
|
CHATLOG_FIL = "chatlog.json" |
|
STEMMETEKST_FIL = "stemmtekst.json" |
|
|
|
api = HfApi() |
|
|
|
|
|
def load_json_from_hf(filename): |
|
try: |
|
content = api.repo_file_download(repo_id=REPO_ID, path_in_repo=filename, token=HF_TOKEN) |
|
with open(content, "r", encoding="utf-8") as f: |
|
return json.load(f) |
|
except Exception: |
|
return {} |
|
|
|
def save_json_to_hf(data, filename): |
|
content = json.dumps(data, ensure_ascii=False, indent=2) |
|
api.upload_file( |
|
path_or_fileobj=content.encode("utf-8"), |
|
path_in_repo=filename, |
|
repo_id=REPO_ID, |
|
repo_type="repo", |
|
token=HF_TOKEN, |
|
commit_message=f"Opdater {filename}", |
|
) |
|
|
|
|
|
def opret_bruger(brugernavn, kodeord, rolle, email): |
|
brugere = load_json_from_hf(BRUGERE_FIL) |
|
if brugernavn in brugere: |
|
return "Brugernavn findes allerede" |
|
|
|
hashed = bcrypt.hashpw(kodeord.encode(), bcrypt.gensalt()).decode() |
|
brugere[brugernavn] = { |
|
"hash": hashed, |
|
"rolle": rolle, |
|
"email": email |
|
} |
|
save_json_to_hf(brugere, BRUGERE_FIL) |
|
return f"Bruger '{brugernavn}' oprettet som {rolle}" |
|
|
|
def tjek_login(brugernavn, kodeord): |
|
brugere = load_json_from_hf(BRUGERE_FIL) |
|
data = brugere.get(brugernavn) |
|
if not data: |
|
return False |
|
return bcrypt.checkpw(kodeord.encode(), data["hash"].encode()) |
|
|
|
|
|
model_name = "NousResearch/Nous-Hermes-2-Mistral-7B-DPO" |
|
tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False) |
|
model = AutoModelForCausalLM.from_pretrained( |
|
model_name, |
|
torch_dtype=torch.float16, |
|
device_map="auto", |
|
trust_remote_code=True |
|
) |
|
|
|
whisper_model = whisper.load_model("base") |
|
|
|
|
|
def dansk_chat(brugernavn, message, history=[]): |
|
prompt = f"Bruger: {message}\nAI:" |
|
inputs = tokenizer(prompt, return_tensors="pt").to("cuda") |
|
outputs = model.generate(**inputs, max_new_tokens=200, pad_token_id=tokenizer.eos_token_id) |
|
response = tokenizer.decode(outputs[0], skip_special_tokens=True) |
|
svar = response.split("AI:")[-1].strip() |
|
|
|
chatlog = load_json_from_hf(CHATLOG_FIL) |
|
now = datetime.utcnow().isoformat() |
|
if brugernavn not in chatlog: |
|
chatlog[brugernavn] = [] |
|
chatlog[brugernavn].append({"timestamp": now, "message": message, "response": svar}) |
|
save_json_to_hf(chatlog, CHATLOG_FIL) |
|
|
|
return svar |
|
|
|
def transskriber(brugernavn, audio): |
|
if audio is None: |
|
return "" |
|
text = whisper_model.transcribe(audio)["text"].strip() |
|
|
|
stemmetekst = load_json_from_hf(STEMMETEKST_FIL) |
|
now = datetime.utcnow().isoformat() |
|
if brugernavn not in stemmetekst: |
|
stemmetekst[brugernavn] = [] |
|
stemmetekst[brugernavn].append({"timestamp": now, "text": text}) |
|
save_json_to_hf(stemmetekst, STEMMETEKST_FIL) |
|
|
|
return text |
|
|
|
|
|
with gr.Blocks() as demo: |
|
with gr.Tab("Opret bruger"): |
|
ny_brugernavn = gr.Textbox(label="Nyt brugernavn") |
|
nyt_kodeord = gr.Textbox(label="Kodeord", type="password") |
|
ny_email = gr.Textbox(label="Email") |
|
rolle_vælger = gr.Dropdown(label="Rolle", choices=["bruger", "super", "admin"], value="bruger") |
|
opret_knap = gr.Button("Opret bruger") |
|
opret_status = gr.Textbox(label="Status", interactive=False) |
|
|
|
with gr.Tab("Login"): |
|
brugernavn = gr.Textbox(label="Brugernavn") |
|
kodeord = gr.Textbox(label="Kodeord", type="password") |
|
login_knap = gr.Button("Login") |
|
login_status = gr.Textbox(label="Status", interactive=False) |
|
|
|
with gr.Tab("Chatbot") as chat_tab: |
|
chat_tab.visible = False |
|
gr.Markdown("## Tal eller skriv med AI'en") |
|
mikrofon = gr.Microphone(type="filepath", label="Tal dansk her") |
|
lyd_tekst = gr.Textbox(label="Transskriberet tekst") |
|
besked = gr.Textbox(label="Eller skriv en besked") |
|
svar = gr.Textbox(label="Svar fra AI") |
|
send_knap = gr.Button("Send") |
|
|
|
|
|
def handle_opret(brugernavn, kodeord, rolle, email): |
|
return opret_bruger(brugernavn, kodeord, rolle, email) |
|
|
|
opret_knap.click(handle_opret, inputs=[ny_brugernavn, nyt_kodeord, rolle_vælger, ny_email], outputs=opret_status) |
|
|
|
def handle_login(bruger, kode): |
|
if tjek_login(bruger, kode): |
|
chat_tab.visible = True |
|
return "Login godkendt" |
|
return "Forkert brugernavn eller kodeord" |
|
|
|
login_knap.click(handle_login, inputs=[brugernavn, kodeord], outputs=login_status) |
|
|
|
mikrofon.change(transskriber, inputs=[brugernavn, mikrofon], outputs=lyd_tekst) |
|
send_knap.click(dansk_chat, inputs=[brugernavn, besked], outputs=svar) |
|
lyd_tekst.change(dansk_chat, inputs=[brugernavn, lyd_tekst], outputs=svar) |
|
|
|
demo.launch() |
|
|