Download app.py from uwe311/qwencoderBoostedWebdev: direct link, hf CLI and curl.
- Browser
- Download file 5.82 kB
-
https://huggingface.co/spaces/uwe311/qwencoderBoostedWebdev/resolve/main/app.py
- Command line
-
hf download hf://spaces/uwe311/qwencoderBoostedWebdev/app.py
-
curl -L -o app.py https://huggingface.co/spaces/uwe311/qwencoderBoostedWebdev/resolve/main/app.py
5.82 kB
| import subprocess, sys, importlib | |
| def ensure_deps(): | |
| """Install missing dependencies at startup.""" | |
| needed = { | |
| "transformers": "transformers>=4.50.0", | |
| "bitsandbytes": "bitsandbytes>=0.45.0", | |
| "accelerate": "accelerate>=1.5.0", | |
| } | |
| missing = [pkg for mod, pkg in needed.items() if importlib.util.find_spec(mod) is None] | |
| if missing: | |
| print(f"π¦ Installiere fehlende Dependencies: {missing}") | |
| subprocess.check_call([sys.executable, "-m", "pip", "install", "--no-cache-dir"] + missing) | |
| print("β Dependencies installiert!") | |
| ensure_deps() | |
| import spaces | |
| import torch | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig | |
| import gradio as gr | |
| import time | |
| # βββ Modell βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| MODEL_ID = "Qwen/Qwen3-Coder-7B-A3B-Instruct" | |
| MAX_TOKENS = 4096 | |
| DEFAULT_TEMP = 0.6 | |
| DEFAULT_SYSTEM = "You are Qwen Coder Boosted, an expert coding assistant. Generate clean, working code. Always show complete files with [FILE:filename] markers." | |
| print("π Lade Modell...") | |
| bnb_config = BitsAndBytesConfig( | |
| load_in_4bit=True, | |
| bnb_4bit_compute_dtype=torch.bfloat16, | |
| bnb_4bit_use_double_quant=True, | |
| bnb_4bit_quant_type="nf4", | |
| ) | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, | |
| quantization_config=bnb_config, | |
| device_map="auto", | |
| trust_remote_code=True, | |
| torch_dtype=torch.bfloat16, | |
| attn_implementation="eager", | |
| ) | |
| print("β Modell geladen!") | |
| # βββ GPU-Funktion (nur hier ist echte GPU) ββββββββββββββββββββββββββββββ | |
| def generate_response(messages, temperature, max_tokens): | |
| """Generate a response from the model. GPU is real inside this function.""" | |
| text = tokenizer.apply_chat_template( | |
| messages, tokenize=False, add_generation_prompt=True | |
| ) | |
| inputs = tokenizer([text], return_tensors="pt").to(model.device) | |
| with torch.no_grad(): | |
| outputs = model.generate( | |
| **inputs, | |
| max_new_tokens=max_tokens, | |
| temperature=temperature, | |
| do_sample=True, | |
| top_p=0.9, | |
| repetition_penalty=1.05, | |
| pad_token_id=tokenizer.eos_token_id, | |
| ) | |
| response = tokenizer.decode( | |
| outputs[0][inputs.input_ids.shape[1]:], skip_special_tokens=True | |
| ) | |
| return response | |
| # βββ Chat-Logik ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def chat(message, history, system_prompt, temperature): | |
| """Handle a chat turn. Builds messages, calls GPU function, returns updated history.""" | |
| if not message.strip(): | |
| return history | |
| messages = [] | |
| if system_prompt: | |
| messages.append({"role": "system", "content": system_prompt}) | |
| for user_msg, assistant_msg in history: | |
| if user_msg: | |
| messages.append({"role": "user", "content": user_msg}) | |
| if assistant_msg: | |
| messages.append({"role": "assistant", "content": assistant_msg}) | |
| messages.append({"role": "user", "content": message}) | |
| response = generate_response(messages, temperature, MAX_TOKENS) | |
| history.append((message, response)) | |
| return history | |
| # βββ UI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| with gr.Blocks( | |
| title="Qwen Coder Boosted", | |
| ) as demo: | |
| gr.Markdown(""" | |
| # π Qwen Coder Boosted | |
| **Qwen3-Coder-30B-A3B (4-bit) auf Zero GPU** β 48 GB shared VRAM, PRO-Quota | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| system_prompt = gr.Textbox( | |
| label="βοΈ System Prompt", | |
| value=DEFAULT_SYSTEM, | |
| lines=3, | |
| ) | |
| temperature = gr.Slider( | |
| label="π‘οΈ Temperature", | |
| minimum=0.1, | |
| maximum=1.5, | |
| value=DEFAULT_TEMP, | |
| step=0.05, | |
| ) | |
| clear_btn = gr.Button("ποΈ Chat leeren", variant="secondary") | |
| with gr.Column(scale=3): | |
| chatbot = gr.Chatbot( | |
| label="π¬ Chat", | |
| height=550, | |
| ) | |
| with gr.Row(): | |
| msg = gr.Textbox( | |
| label="Deine Nachricht", | |
| placeholder="Schreib einen Prompt... z.B. 'Baue eine To-Do-App mit HTML/CSS/JS'", | |
| scale=8, | |
| container=True, | |
| ) | |
| submit = gr.Button("π€ Senden", variant="primary", scale=1) | |
| gr.Markdown(""" | |
| --- | |
| ### π‘ Info | |
| - **Modell:** Qwen3-Coder-30B-A3B (4-bit, ~15 GB VRAM) | |
| - **Zero GPU:** 48 GB shared, PRO = 40 Min/Tag inklusive | |
| - **Max Tokens:** 32K (hardcodiert) | |
| - **Temperature:** 0.6 (Standard fΓΌr Coding) | |
| """) | |
| submit.click( | |
| fn=chat, | |
| inputs=[msg, chatbot, system_prompt, temperature], | |
| outputs=[chatbot], | |
| ).then( | |
| fn=lambda: "", | |
| outputs=[msg], | |
| ) | |
| msg.submit( | |
| fn=chat, | |
| inputs=[msg, chatbot, system_prompt, temperature], | |
| outputs=[chatbot], | |
| ).then( | |
| fn=lambda: "", | |
| outputs=[msg], | |
| ) | |
| clear_btn.click(fn=lambda: None, outputs=[chatbot]) | |
| if __name__ == "__main__": | |
| demo.launch(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="indigo")) | |