polats's picture
Stream Tiny Aya text generation
f5021d4
Raw
History Blame Contribute Delete
4.05 kB
from __future__ import annotations
import os
import threading
os.environ.setdefault("OPENBLAS_NUM_THREADS", "4")
os.environ.setdefault("OMP_NUM_THREADS", "4")
os.environ.setdefault("MKL_NUM_THREADS", "4")
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
os.environ.setdefault("GRADIO_SSR_MODE", "false")
import gradio as gr
import spaces
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
MODEL_ID = os.environ.get("TINY_AYA_MODEL", "CohereLabs/tiny-aya-global")
DEFAULT_MAX_TOKENS = int(os.environ.get("TINY_AYA_MAX_TOKENS", "400"))
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype="auto")
if torch.cuda.is_available():
model.to("cuda")
model.eval()
_lock = threading.Lock()
def _messages(system: str, user: str):
messages = []
if system and system.strip():
messages.append({"role": "system", "content": system.strip()})
messages.append({"role": "user", "content": (user or "").strip()})
return messages
@spaces.GPU(duration=120)
def generate(system: str, user: str, max_tokens: int = DEFAULT_MAX_TOKENS, temperature: float = 0.8):
if not user or not user.strip():
raise gr.Error("user prompt required")
max_tokens = max(1, min(int(max_tokens or DEFAULT_MAX_TOKENS), 1024))
temperature = max(0.0, min(float(temperature if temperature is not None else 0.8), 2.0))
inputs = tokenizer.apply_chat_template(
_messages(system, user),
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",
).to(model.device)
with _lock, torch.inference_mode():
outputs = model.generate(
**inputs,
max_new_tokens=max_tokens,
do_sample=temperature > 0,
temperature=max(temperature, 1e-5),
top_p=0.95,
pad_token_id=tokenizer.eos_token_id,
)
return tokenizer.decode(outputs[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True).strip()
@spaces.GPU(duration=120)
def generate_stream(system: str, user: str, max_tokens: int = DEFAULT_MAX_TOKENS, temperature: float = 0.8):
if not user or not user.strip():
raise gr.Error("user prompt required")
max_tokens = max(1, min(int(max_tokens or DEFAULT_MAX_TOKENS), 1024))
temperature = max(0.0, min(float(temperature if temperature is not None else 0.8), 2.0))
inputs = tokenizer.apply_chat_template(
_messages(system, user),
tokenize=True,
add_generation_prompt=True,
return_dict=True,
return_tensors="pt",
).to(model.device)
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)
def run():
with _lock, torch.inference_mode():
model.generate(
**inputs,
max_new_tokens=max_tokens,
do_sample=temperature > 0,
temperature=max(temperature, 1e-5),
top_p=0.95,
pad_token_id=tokenizer.eos_token_id,
streamer=streamer,
)
thread = threading.Thread(target=run, daemon=True)
thread.start()
acc = ""
for token in streamer:
acc += token
yield acc
thread.join(timeout=1)
with gr.Blocks(title="Tiny Army Tiny Aya ZeroGPU") as demo:
gr.Markdown("# Tiny Army Tiny Aya ZeroGPU")
system = gr.Textbox(label="System", lines=5)
user = gr.Textbox(label="User", lines=5)
max_tokens = gr.Slider(1, 1024, value=DEFAULT_MAX_TOKENS, step=1, label="Max new tokens")
temperature = gr.Slider(0, 2, value=0.8, step=0.05, label="Temperature")
btn = gr.Button("Generate")
out = gr.Textbox(label="Output", lines=10)
btn.click(generate, inputs=[system, user, max_tokens, temperature], outputs=out, api_name="generate")
btn.click(generate_stream, inputs=[system, user, max_tokens, temperature], outputs=out, api_name="generate_stream")
if __name__ == "__main__":
demo.launch()