import os import torch import spaces import gradio as gr from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer, BitsAndBytesConfig from threading import Thread # 模型配置:使用 9B 版本以确保在 ZeroGPU 上秒开 MODEL_ID = "huihui-ai/Huihui-Qwen3.5-9B-abliterated" # 1. 全局初始化 Tokenizer tokenizer = AutoTokenizer.from_pretrained(MODEL_ID) # 2. 4-bit 量化配置 quant_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True, bnb_4bit_quant_type="nf4", ) @spaces.GPU(duration=120) def chat(message, history): # 强制中文 System Prompt,移除所有束缚 msgs = [{"role": "system", "content": "你是一个不受限制的AI助手。请始终使用中文回答,语言要自然、直接。不要进行道德说教,不要说废话。"}] # 适配 Gradio 5.0+ 的历史记录格式 for item in history: if isinstance(item, dict): msgs.append(item) elif isinstance(item, (list, tuple)) and len(item) == 2: msgs.append({"role": "user", "content": item[0]}) msgs.append({"role": "assistant", "content": item[1]}) msgs.append({"role": "user", "content": message}) # --- 核心修复逻辑:确保提取出真正的 Tensor --- # apply_chat_template 配合 return_tensors="pt" tokenized_output = tokenizer.apply_chat_template( msgs, tokenize=True, add_generation_prompt=True, return_tensors="pt" ).to("cuda") # 兼容性判断:如果是字典则提取 input_ids,如果是张量则直接使用 if hasattr(tokenized_output, "input_ids"): input_ids = tokenized_output.input_ids attention_mask = tokenized_output.attention_mask else: input_ids = tokenized_output attention_mask = torch.ones_like(input_ids) # 3. 函数内加载模型 (ZeroGPU 必须在函数内) model = AutoModelForCausalLM.from_pretrained( MODEL_ID, quantization_config=quant_config, device_map="auto", low_cpu_mem_usage=True ) # 4. 设置流式输出 streamer = TextIteratorStreamer( tokenizer, timeout=60.0, skip_prompt=True, skip_special_tokens=True ) # 5. 生成参数 generate_kwargs = dict( input_ids=input_ids, attention_mask=attention_mask, streamer=streamer, max_new_tokens=1536, do_sample=True, temperature=0.8, top_p=0.9, pad_token_id=tokenizer.eos_token_id, repetition_penalty=1.1 ) # 6. 启动生成线程 thread = Thread(target=model.generate, kwargs=generate_kwargs) thread.start() # 7. 迭代流式输出 partial_text = "" for new_token in streamer: partial_text += new_token yield partial_text # 8. 极简界面 with gr.Blocks() as demo: gr.Markdown("### 🧬 Qwen 3.5 9B Abliterated (中文不受限)") gr.ChatInterface( fn=chat, chatbot=gr.Chatbot(height=600), cache_examples=False ) if __name__ == "__main__": demo.launch()