SEE7 commited on
Commit
0339afd
·
verified ·
1 Parent(s): 7312ec4

Deploy private Astheral demo with real weights on ZeroGPU

Browse files
Files changed (3) hide show
  1. README.md +30 -6
  2. app.py +91 -0
  3. requirements.txt +5 -0
README.md CHANGED
@@ -1,13 +1,37 @@
1
  ---
2
  title: Astheral
3
- emoji: 🌖
4
- colorFrom: gray
5
- colorTo: yellow
6
  sdk: gradio
7
- sdk_version: 6.32.0
8
- python_version: '3.13'
9
  app_file: app.py
 
10
  pinned: false
 
 
 
 
11
  ---
 
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Astheral
3
+ emoji: ✨
4
+ colorFrom: indigo
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 5.49.1
8
+ python_version: "3.10"
9
  app_file: app.py
10
+ hf_oauth: true
11
  pinned: false
12
+ license: llama3.1
13
+ models:
14
+ - SEE7/Astheral
15
+ short_description: Real Astheral 8.03B weights with streaming ZeroGPU inference
16
  ---
17
+ # Astheral
18
 
19
+ **Built with Llama.** This Space runs the actual merged weights from [SEE7/Astheral](https://huggingface.co/SEE7/Astheral), fine-tuned from DeepHermes 3 / Llama 3.1 8B. No mock replies, base-model substitution, or external inference API.
20
+
21
+ Model revision: `d9aa899722be4788f57107c2951c72d0ec6614ee`.
22
+
23
+ ## Hosting and costs
24
+
25
+ Private owner-use deployment to avoid exposing your prepaid credits to public traffic. Configured for Hugging Face ZeroGPU, using the default GPU size. Requires ZeroGPU hardware to remain selected in Settings. No CPU inference fallback and no paid dedicated GPU is configured.
26
+
27
+ As documented by Hugging Face at deployment, PRO includes 40 GPU minutes per day with higher queue priority. Beyond that allowance, ZeroGPU can automatically consume prepaid credits at $1 per 10 GPU minutes. This application does not implement an account-wide billing cap. Monitor your billing and quota in Hugging Face settings.
28
+
29
+ ZeroGPU is shared: GPU queues and cold starts can add latency. Replies stream when generation starts. Each request reserves up to 30 GPU seconds, with generation targeting 23 seconds, 2,048 input tokens, and a default 192 output tokens. Only one generation runs at once.
30
+
31
+ ## Modes
32
+
33
+ Instruct and Thinking use the model's published settings.json. Thinking uses the model's existing visible worked-solution format and may reach the output limit. The model and tokenizer are pinned to the same repository revision.
34
+
35
+ ## Licensing
36
+
37
+ See the [model card and license](https://huggingface.co/SEE7/Astheral). Llama 3.1 licensing and attribution apply.
app.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
3
+
4
+ import spaces
5
+ import json
6
+ from threading import Thread
7
+ import gradio as gr
8
+ import torch
9
+ from huggingface_hub import hf_hub_download
10
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
11
+
12
+ MODEL_ID = "SEE7/Astheral"
13
+ MODEL_REVISION = "d9aa899722be4788f57107c2951c72d0ec6614ee"
14
+ settings = json.load(open(hf_hub_download(MODEL_ID, "settings.json", revision=MODEL_REVISION)))
15
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, revision=MODEL_REVISION)
16
+ model = AutoModelForCausalLM.from_pretrained(
17
+ MODEL_ID, revision=MODEL_REVISION, torch_dtype=torch.bfloat16,
18
+ device_map={"": "cuda"}, low_cpu_mem_usage=True,
19
+ attn_implementation="sdpa", use_safetensors=True,
20
+ ).eval()
21
+
22
+ @spaces.GPU(duration=30)
23
+ def respond(message, history, max_tokens, temperature, mode, request: gr.Request):
24
+ if not message or not message.strip():
25
+ raise gr.Error("Enter a message first.")
26
+ if len(message) > 12000:
27
+ raise gr.Error("Please keep your message under 12,000 characters.")
28
+ system = settings["system"]
29
+ if mode == "Thinking":
30
+ system += "\n" + settings["thinking"]
31
+ messages = [{"role": "system", "content": system}]
32
+ # Keep the system instruction and the most recent complete turns within 2K tokens.
33
+ turns = [item for item in history[-12:] if item.get("role") in ("user", "assistant") and isinstance(item.get("content"), str)]
34
+ latest = {"role": "user", "content": message.strip()}
35
+ while turns and len(tokenizer.apply_chat_template(messages + turns + [latest], tokenize=True, add_generation_prompt=True)) > 2048:
36
+ turns = turns[2:]
37
+ inputs = tokenizer.apply_chat_template(
38
+ messages + turns + [latest], tokenize=True, add_generation_prompt=True,
39
+ return_dict=True, return_tensors="pt",
40
+ )
41
+ if inputs["input_ids"].shape[1] > 2048:
42
+ raise gr.Error("That message is too long for this budget-friendly demo. Please shorten it.")
43
+ inputs = inputs.to("cuda")
44
+ streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True, timeout=28)
45
+ generation = dict(
46
+ **inputs, streamer=streamer, max_new_tokens=int(max_tokens),
47
+ do_sample=float(temperature) > 0, max_time=23,
48
+ pad_token_id=128004, eos_token_id=128009,
49
+ )
50
+ if float(temperature) > 0:
51
+ generation.update(temperature=float(temperature), top_p=0.9)
52
+ errors = []
53
+ def generate():
54
+ try:
55
+ with torch.inference_mode():
56
+ model.generate(**generation)
57
+ except Exception as exc:
58
+ errors.append(exc)
59
+ streamer.end()
60
+ worker = Thread(target=generate, daemon=True)
61
+ worker.start()
62
+ response = ""
63
+ try:
64
+ for text in streamer:
65
+ response += text
66
+ yield response
67
+ finally:
68
+ worker.join(timeout=2)
69
+ if errors:
70
+ raise gr.Error("Generation failed. Please retry with a shorter prompt.") from errors[0]
71
+ if not response.strip():
72
+ raise gr.Error("No text was generated. Please try again.")
73
+
74
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo"), title="Astheral · Built with Llama") as demo:
75
+ gr.Markdown("# Astheral\n**Built with Llama · SEE7's real 8.03B model · ZeroGPU**")
76
+ gr.Markdown("Chat with the published Astheral weights. Replies stream as they are generated. Shared GPU queues and cold starts can add a wait.")
77
+ gr.LoginButton()
78
+ with gr.Accordion("Response settings", open=False):
79
+ max_tokens = gr.Slider(32, 512, value=192, step=32, label="Maximum new tokens")
80
+ temperature = gr.Slider(0, 1, value=0.6, step=0.1, label="Temperature (0 = deterministic)")
81
+ mode = gr.Radio(["Instruct", "Thinking"], value="Instruct", label="Mode")
82
+ gr.Markdown("To conserve GPU quota, each reply has a 23-second generation time target. Thinking may need more tokens to finish.")
83
+ gr.ChatInterface(
84
+ fn=respond, type="messages", additional_inputs=[max_tokens, temperature, mode],
85
+ examples=["Explain Python generators in three sentences.", "Write a short starship announcement."],
86
+ cache_examples=False, concurrency_limit=1, api_name="chat",
87
+ )
88
+ gr.Markdown("ZeroGPU usage follows your Hugging Face quota. PRO currently includes 40 GPU minutes/day; usage beyond the included quota can automatically consume prepaid credits. [Check billing](https://huggingface.co/settings/billing) · [Model and license](https://huggingface.co/SEE7/Astheral)")
89
+ demo.queue(max_size=6, default_concurrency_limit=1)
90
+ if __name__ == "__main__":
91
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ spaces
2
+ torch==2.8.0
3
+ transformers==4.57.1
4
+ accelerate==1.11.0
5
+ gradio==5.49.1