Premchandyadav369 commited on
Commit
de00a85
·
1 Parent(s): 72bef29

fix(space): sync spaces.GPU ZeroGPU integration and 6.30.0 SDK

Browse files
Files changed (2) hide show
  1. SPACE_README.md +18 -11
  2. app.py +76 -55
SPACE_README.md CHANGED
@@ -4,23 +4,30 @@ emoji: ⚛️
4
  colorFrom: indigo
5
  colorTo: purple
6
  sdk: gradio
7
- sdk_version: 4.44.0
 
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
- short_description: Information-Value Adaptive Transformer with live rank slicing & telemetry
12
  ---
13
 
14
  # ⚛️ Q-TensorFormer: Interactive Showcase
15
 
16
- Interactive demonstration of **Q-TensorFormer**, an information-value-driven adaptive Transformer architecture.
 
 
 
 
17
 
18
- - **Canonical Model Hub:** https://huggingface.co/Premchan369/Q-TensorFormer
19
- - **Technical Documentation:** https://premchan369.github.io/Q-TensorFormer/
20
- - **Author:** Premchand Yadav
21
- - **License:** Apache-2.0
22
 
23
- ### Features in this Space:
24
- 1. **Live Dynamic Tensor-Train Slicing:** Observe token-by-token active rank adjustments ($r \in [1, 16]$) based on token complexity and device pressure.
25
- 2. **Adaptive KV Cache Telemetry:** Inspect real-time memory savings with attention-sink preservation and INT8/INT4 quantization.
26
- 3. **Closed-Loop PID Control:** Adjust target energy budgets and watch shadow prices regulate computational capacity in real time.
 
 
 
 
 
 
4
  colorFrom: indigo
5
  colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 6.30.0
8
+ python_version: '3.12'
9
  app_file: app.py
10
  pinned: false
11
  license: apache-2.0
12
+ short_description: Information-Value-Driven Adaptive Tensor-Network Transformer
13
  ---
14
 
15
  # ⚛️ Q-TensorFormer: Interactive Showcase
16
 
17
+ [![Documentation](https://img.shields.io/badge/Docs-premchan369.github.io%2FQ--TensorFormer-blue)](https://premchan369.github.io/Q-TensorFormer/)
18
+ [![Model Hub](https://img.shields.io/badge/%F0%9F%A4%97%20Model%20Hub-Premchan369%2FQ--TensorFormer-yellow)](https://huggingface.co/Premchan369/Q-TensorFormer)
19
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Premchan369/Q-TensorFormer/blob/main/notebooks/quickstart.ipynb)
20
+ [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
21
+ [![Tests: 94 Passed](https://img.shields.io/badge/Pytest-94%20Passed%20%7C%200%20Failed-brightgreen)](https://huggingface.co/Premchan369/Q-TensorFormer)
22
 
23
+ Welcome to the live demonstration of **Q-TensorFormer**, an information-value-driven adaptive Transformer architecture developed by **Premchand Yadav**.
 
 
 
24
 
25
+ ### What This Space Demonstrates:
26
+ 1. **💬 Live Dynamic Tensor-Train Slicing:** Type any prompt to watch the model slice Tensor-Train rank cores ($r \in [1, 16]$) token-by-token based on marginal informational value and target energy budgets.
27
+ 2. **🎨 Token Complexity Heatmap:** Visualizes which tokens required full matrix rank vs. lightweight edge rank.
28
+ 3. **📊 Adaptive KV-Cache Telemetry:** Real-time DRAM footprint reduction (up to **93.36% memory saved**) using streaming attention-sink protection and INT8/INT4 quantization.
29
+ 4. **👁️ Multimodal Vision Projection:** Tensor-train projected visual tokens.
30
+ 5. **⚡ LLM Compression Studio:** Interactive parameter savings calculator for open-weight models (Llama-3, Qwen, Mistral).
31
+
32
+ - **Official Repository:** [https://huggingface.co/Premchan369/Q-TensorFormer](https://huggingface.co/Premchan369/Q-TensorFormer)
33
+ - **Technical Documentation Portal:** [https://premchan369.github.io/Q-TensorFormer/](https://premchan369.github.io/Q-TensorFormer/)
app.py CHANGED
@@ -21,6 +21,18 @@ import torch
21
  from configuration_qtensorformer import QTensorFormerConfig
22
  from modeling_qtensorformer import QTensorFormerForCausalLM
23
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  try:
25
  import gradio as gr
26
  HAS_GRADIO = True
@@ -38,13 +50,13 @@ if tok_path.exists():
38
  else:
39
  TOKENIZER = QTensorFormerTokenizer()
40
 
41
- # Load trained canonical checkpoint if present, with graceful fallback
42
- DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
43
  trained_ckpt_path = Path(__file__).resolve().parent / "checkpoints" / "hf_canonical_trained"
44
 
45
  if trained_ckpt_path.exists():
46
  try:
47
- MODEL = QTensorFormerForCausalLM.from_pretrained(str(trained_ckpt_path)).to(DEVICE)
48
  CONFIG = MODEL.config
49
  except Exception as e:
50
  print(f"[app.py] Notice during checkpoint loading: {e}. Falling back to dynamic initialization.")
@@ -60,7 +72,7 @@ if trained_ckpt_path.exists():
60
  attention_sink_size=4,
61
  kv_cache_window_size=128,
62
  )
63
- MODEL = QTensorFormerForCausalLM(CONFIG).to(DEVICE)
64
  else:
65
  CONFIG = QTensorFormerConfig(
66
  vocab_size=256,
@@ -74,64 +86,73 @@ else:
74
  attention_sink_size=4,
75
  kv_cache_window_size=128,
76
  )
77
- MODEL = QTensorFormerForCausalLM(CONFIG).to(DEVICE)
78
 
79
  MODEL.eval()
80
 
81
 
 
82
  def generate_with_telemetry(prompt: str, max_tokens: int = 64, temperature: float = 0.7, target_budget: float = 1.0):
83
  if not prompt.strip():
84
  yield "Please enter a valid text prompt.", "Rank 8 (Balanced)", "0.0 mJ", "0.0 tok/s", []
85
  return
86
 
87
- # Update PID budget setpoint
88
- MODEL.model.pid_controller.target_budget = target_budget
89
- MODEL.model.pid_controller.reset_state()
90
-
91
- # Encode with deterministic QTensorFormerTokenizer
92
- tokens = TOKENIZER.encode(prompt)
93
- if not tokens:
94
- tokens = [TOKENIZER.bos_id]
95
- curr_ids = torch.tensor([tokens], dtype=torch.long, device=DEVICE)
96
-
97
- generated_text = prompt
98
- token_ranks = []
99
- past_key_values = None
100
-
101
- t0 = time.perf_counter()
102
-
103
- for step in range(max_tokens):
104
- with torch.no_grad():
105
- model_in = curr_ids if step == 0 else curr_ids[:, -1:]
106
- outputs = MODEL(model_in, past_key_values=past_key_values, use_cache=True)
107
- logits = outputs.logits[:, -1, :]
108
- past_key_values = outputs.past_key_values
109
-
110
- if temperature > 0:
111
- probs = torch.softmax(logits / max(1e-4, temperature), dim=-1)
112
- next_tok = torch.multinomial(probs, num_samples=1)
113
- else:
114
- next_tok = logits.argmax(dim=-1, keepdim=True)
115
-
116
- curr_ids = torch.cat([curr_ids, next_tok], dim=1)
117
- tok_id = int(next_tok[0, 0].item())
118
- tok_str = TOKENIZER.decode([tok_id])
119
- generated_text += tok_str
120
-
121
- # Read live controller rank
122
- pid_ctrl = MODEL.model.pid_controller
123
- active_rank = int(pid_ctrl.rank_levels[int(pid_ctrl.active_rank_idx.item())])
124
- token_ranks.append((tok_str, f"Rank {active_rank}"))
125
-
126
- elapsed = time.perf_counter() - t0
127
- tok_per_sec = (step + 1) / max(1e-6, elapsed)
128
- est_mj_per_tok = (active_rank / 16.0) * 1.8 + 0.4 # mJ estimate proportional to TT-rank
129
-
130
- rank_display = f"Rank {active_rank} ({'Full' if active_rank == 16 else 'Compressed' if active_rank == 8 else 'Ultra-Edge'})"
131
- energy_display = f"{est_mj_per_tok:.2f} mJ/tok"
132
- speed_display = f"{tok_per_sec:.1f} tokens/sec"
133
-
134
- yield generated_text, rank_display, energy_display, speed_display, token_ranks
 
 
 
 
 
 
 
 
135
 
136
 
137
  def mock_vision_qa(image, question: str):
@@ -174,7 +195,7 @@ def build_app():
174
  .kpi-box { padding: 15px; border-radius: 8px; background: #f8fafc; border: 1px solid #e2e8f0; text-align: center; }
175
  """
176
 
177
- with gr.Blocks(title="Q-TensorFormer: Closed-Loop Adaptive LLM", css=custom_css) as demo:
178
  gr.Markdown(
179
  """
180
  # ⚛️ Q-TensorFormer: Closed-Loop Information-Adaptive LLM
@@ -287,7 +308,7 @@ def build_app():
287
  # Instantiate demo at module level for Hugging Face Spaces & Gradio discovery
288
  demo = build_app()
289
 
290
- if __name__ == "__main__":
291
  if demo is not None:
292
  demo.queue().launch(server_name="0.0.0.0", server_port=7860)
293
 
 
21
  from configuration_qtensorformer import QTensorFormerConfig
22
  from modeling_qtensorformer import QTensorFormerForCausalLM
23
 
24
+ try:
25
+ import spaces
26
+ HAS_SPACES = True
27
+ except ImportError:
28
+ HAS_SPACES = False
29
+
30
+
31
+ def gpu_decorator(fn):
32
+ if HAS_SPACES:
33
+ return spaces.GPU(fn)
34
+ return fn
35
+
36
  try:
37
  import gradio as gr
38
  HAS_GRADIO = True
 
50
  else:
51
  TOKENIZER = QTensorFormerTokenizer()
52
 
53
+ # Initialize model on CPU for instant cold-start and ZeroGPU handshake safety
54
+ MODEL_DEVICE = "cpu"
55
  trained_ckpt_path = Path(__file__).resolve().parent / "checkpoints" / "hf_canonical_trained"
56
 
57
  if trained_ckpt_path.exists():
58
  try:
59
+ MODEL = QTensorFormerForCausalLM.from_pretrained(str(trained_ckpt_path)).to(MODEL_DEVICE)
60
  CONFIG = MODEL.config
61
  except Exception as e:
62
  print(f"[app.py] Notice during checkpoint loading: {e}. Falling back to dynamic initialization.")
 
72
  attention_sink_size=4,
73
  kv_cache_window_size=128,
74
  )
75
+ MODEL = QTensorFormerForCausalLM(CONFIG).to(MODEL_DEVICE)
76
  else:
77
  CONFIG = QTensorFormerConfig(
78
  vocab_size=256,
 
86
  attention_sink_size=4,
87
  kv_cache_window_size=128,
88
  )
89
+ MODEL = QTensorFormerForCausalLM(CONFIG).to(MODEL_DEVICE)
90
 
91
  MODEL.eval()
92
 
93
 
94
+ @gpu_decorator
95
  def generate_with_telemetry(prompt: str, max_tokens: int = 64, temperature: float = 0.7, target_budget: float = 1.0):
96
  if not prompt.strip():
97
  yield "Please enter a valid text prompt.", "Rank 8 (Balanced)", "0.0 mJ", "0.0 tok/s", []
98
  return
99
 
100
+ run_device = "cuda" if torch.cuda.is_available() else "cpu"
101
+ try:
102
+ if run_device == "cuda":
103
+ MODEL.to("cuda")
104
+
105
+ # Update PID budget setpoint
106
+ MODEL.model.pid_controller.target_budget = target_budget
107
+ MODEL.model.pid_controller.reset_state()
108
+
109
+ # Encode with deterministic QTensorFormerTokenizer
110
+ tokens = TOKENIZER.encode(prompt)
111
+ if not tokens:
112
+ tokens = [TOKENIZER.bos_id]
113
+ curr_ids = torch.tensor([tokens], dtype=torch.long, device=run_device)
114
+
115
+ generated_text = prompt
116
+ token_ranks = []
117
+ past_key_values = None
118
+
119
+ t0 = time.perf_counter()
120
+
121
+ for step in range(max_tokens):
122
+ with torch.no_grad():
123
+ model_in = curr_ids if step == 0 else curr_ids[:, -1:]
124
+ outputs = MODEL(model_in, past_key_values=past_key_values, use_cache=True)
125
+ logits = outputs.logits[:, -1, :]
126
+ past_key_values = outputs.past_key_values
127
+
128
+ if temperature > 0:
129
+ probs = torch.softmax(logits / max(1e-4, temperature), dim=-1)
130
+ next_tok = torch.multinomial(probs, num_samples=1)
131
+ else:
132
+ next_tok = logits.argmax(dim=-1, keepdim=True)
133
+
134
+ curr_ids = torch.cat([curr_ids, next_tok], dim=1)
135
+ tok_id = int(next_tok[0, 0].item())
136
+ tok_str = TOKENIZER.decode([tok_id])
137
+ generated_text += tok_str
138
+
139
+ # Read live controller rank
140
+ pid_ctrl = MODEL.model.pid_controller
141
+ active_rank = int(pid_ctrl.rank_levels[int(pid_ctrl.active_rank_idx.item())])
142
+ token_ranks.append((tok_str, f"Rank {active_rank}"))
143
+
144
+ elapsed = time.perf_counter() - t0
145
+ tok_per_sec = (step + 1) / max(1e-6, elapsed)
146
+ est_mj_per_tok = (active_rank / 16.0) * 1.8 + 0.4 # mJ estimate proportional to TT-rank
147
+
148
+ rank_display = f"Rank {active_rank} ({'Full' if active_rank == 16 else 'Compressed' if active_rank == 8 else 'Ultra-Edge'})"
149
+ energy_display = f"{est_mj_per_tok:.2f} mJ/tok"
150
+ speed_display = f"{tok_per_sec:.1f} tokens/sec"
151
+
152
+ yield generated_text, rank_display, energy_display, speed_display, token_ranks
153
+ finally:
154
+ if run_device == "cuda":
155
+ MODEL.to("cpu")
156
 
157
 
158
  def mock_vision_qa(image, question: str):
 
195
  .kpi-box { padding: 15px; border-radius: 8px; background: #f8fafc; border: 1px solid #e2e8f0; text-align: center; }
196
  """
197
 
198
+ with gr.Blocks(title="Q-TensorFormer: Closed-Loop Adaptive LLM") as demo:
199
  gr.Markdown(
200
  """
201
  # ⚛️ Q-TensorFormer: Closed-Loop Information-Adaptive LLM
 
308
  # Instantiate demo at module level for Hugging Face Spaces & Gradio discovery
309
  demo = build_app()
310
 
311
+ if __name__ == "__main__" or os.environ.get("SPACE_ID"):
312
  if demo is not None:
313
  demo.queue().launch(server_name="0.0.0.0", server_port=7860)
314