Spaces:
Running on Zero
Running on Zero
File size: 4,753 Bytes
306debd 58a1d31 306debd 903166e 58a1d31 306debd 5d6a8dd 58a1d31 eb3d588 dab1096 58a1d31 7e20c5d 5d6a8dd b8795e6 58a1d31 dab1096 a67f3c8 58a1d31 7e20c5d e460a69 99133af e460a69 5aa6b15 6aa6439 e7834dd 7e20c5d 58a1d31 7e20c5d 58a1d31 7e20c5d b8795e6 7e20c5d 58a1d31 7e20c5d 58a1d31 f1c2303 6756da9 1b0b128 58a1d31 7e20c5d 58a1d31 7e20c5d 58a1d31 7e20c5d 58a1d31 5aa6b15 7e20c5d 5aa6b15 7e20c5d 58a1d31 0449664 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import gradio as gr
import torch
import spaces
import sys
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread
import transformers.modeling_rope_utils as rope_utils
from huggingface_hub import hf_hub_download
# 1. Monkey-patch dynamic_rope_update if missing
if not hasattr(rope_utils, 'dynamic_rope_update'):
def dynamic_rope_update(rope_forward):
return rope_forward
rope_utils.dynamic_rope_update = dynamic_rope_update
model_id = "deepgrove/maple-preview"
print("π Loading tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
# Explicitly load chat template
try:
template_path = hf_hub_download(repo_id=model_id, filename="chat_template.jinja")
with open(template_path, "r", encoding="utf-8") as f:
tokenizer.chat_template = f.read()
print("β
Chat template loaded successfully.")
except Exception as e:
print(f"β οΈ Warning: Could not load chat template: {e}")
print("π Loading Maple-Preview...")
model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="auto",
torch_dtype=torch.bfloat16,
trust_remote_code=True,
)
# 2. Aggressively replace the buggy fa3 wrapper in EVERY loaded module namespace
def custom_flash_attention_forward(
query_states, key_states, value_states, attention_mask=None, query_length=None,
is_causal=True, dropout=0.0, position_ids=None, softmax_scale=None, **kwargs
):
from flash_attn import flash_attn_func, flash_attn_varlen_func
if query_states.dim() == 3:
cu_seq_lens_q = torch.tensor([0, query_states.shape[0]], dtype=torch.int32, device=query_states.device)
cu_seq_lens_k = torch.tensor([0, key_states.shape[0]], dtype=torch.int32, device=key_states.device)
return flash_attn_varlen_func(
query_states, key_states, value_states,
cu_seqlens_q=cu_seq_lens_q, cu_seqlens_k=cu_seq_lens_k,
max_seqlen_q=query_states.shape[0], max_seqlen_k=key_states.shape[0],
dropout_p=dropout, softmax_scale=softmax_scale, causal=is_causal
)
return flash_attn_func(
query_states, key_states, value_states,
dropout_p=dropout, softmax_scale=softmax_scale, causal=is_causal
)
patched_count = 0
for name, module in list(sys.modules.items()):
if 'maple' in name and hasattr(module, '_flash_attention_forward'):
setattr(module, '_flash_attention_forward', custom_flash_attention_forward)
patched_count += 1
print(f"β
Replaced _flash_attention_forward in {patched_count} modules.")
@spaces.GPU
def predict(message, history):
messages = history + [{"role": "user", "content": message}]
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
generation_kwargs = dict(
**inputs,
streamer=streamer,
max_new_tokens=2048,
do_sample=True,
temperature=0.7,
top_p=0.9,
repetition_penalty=1.15,
no_repeat_ngram_size=3,
pad_token_id=tokenizer.pad_token_id,
eos_token_id=tokenizer.eos_token_id,
)
thread = Thread(target=model.generate, kwargs=generation_kwargs)
thread.start()
generated_text = ""
for new_text in streamer:
generated_text += new_text
# Format thinking tags into a collapsible HTML dropdown element
formatted_text = generated_text
if "<think>" in formatted_text:
if "</think>" in formatted_text:
formatted_text = formatted_text.replace("<think>", "<details><summary>π§ Thought Process</summary>\n\n").replace("</think>", "\n\n</details>\n\n---")
else:
formatted_text = formatted_text.replace("<think>", "<details><summary>π§ Thought Process (Thinking...)</summary>\n\n") + "\n\n</details>"
yield formatted_text
# 3. Custom Chatbot component with Copy & Copy All features enabled
chatbot_ui = gr.Chatbot(
type="messages",
show_copy_button=True, # Adds a copy button to individual messages
show_copy_all_button=True, # Adds a button to copy the entire conversation history
allow_file_downloads=True,
)
demo = gr.ChatInterface(
fn=predict,
type="messages",
chatbot=chatbot_ui,
title="π Maple-Preview",
description="A 20B-A1B ternary-weight reasoning LLM by DeepGrove. Powered by ZeroGPU.",
theme="soft",
)
if __name__ == "__main__":
demo.queue().launch() |