electblake commited on
Commit
b5b0ab9
·
0 Parent(s):

one-shot 5.6 sol

Browse files
Files changed (6) hide show
  1. .gitignore +11 -0
  2. README.md +22 -0
  3. app.py +185 -0
  4. mise.toml +7 -0
  5. pyproject.toml +25 -0
  6. requirements.txt +9 -0
.gitignore ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+ uv.lock
README.md ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Spreadsheet Data Agent
3
+ emoji: 📊
4
+ colorFrom: blue
5
+ colorTo: pink
6
+ sdk: gradio
7
+ sdk_version: 6.24.0
8
+ app_file: app.py
9
+ pinned: false
10
+ license: apache-2.0
11
+ models:
12
+ - Spreadsheet-RL/Spreadsheet-RL-4B
13
+ - mradermacher/Spreadsheet-RL-4B-GGUF
14
+ ---
15
+
16
+ # Spreadsheet Data Agent
17
+
18
+ A basic text-and-file inference app for Spreadsheet-RL-4B, modeled on the prompt entry point in the Spreadsheet-RL agent-system diagram.
19
+
20
+ The app accepts a system prompt, user prompt, and optional text or spreadsheet file. Its quantization selector exposes the 4B GGUF variants captured in the project reference material, with Q4_K_M selected by default.
21
+
22
+ ZeroGPU support is enabled with the `spaces` package and `@spaces.GPU`. Select ZeroGPU in the Hugging Face Space hardware settings after deployment.
app.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from gc import collect
2
+ from pathlib import Path
3
+
4
+ import gradio as gr
5
+ import pandas as pd
6
+ import spaces
7
+ import torch
8
+ from huggingface_hub import hf_hub_download
9
+ from transformers import AutoModelForCausalLM, AutoTokenizer
10
+
11
+
12
+ MODEL_REPO = "mradermacher/Spreadsheet-RL-4B-GGUF"
13
+ QUANT_FILES = {
14
+ "Q2_K · 1.9 GB": "Spreadsheet-RL-4B.Q2_K.gguf",
15
+ "Q3_K_S · 2.2 GB": "Spreadsheet-RL-4B.Q3_K_S.gguf",
16
+ "Q3_K_M · 2.3 GB · lower quality": "Spreadsheet-RL-4B.Q3_K_M.gguf",
17
+ "Q3_K_L · 2.5 GB": "Spreadsheet-RL-4B.Q3_K_L.gguf",
18
+ "IQ4_XS · 2.6 GB": "Spreadsheet-RL-4B.IQ4_XS.gguf",
19
+ "Q4_K_S · 2.7 GB · recommended": "Spreadsheet-RL-4B.Q4_K_S.gguf",
20
+ "Q4_K_M · 2.8 GB · recommended": "Spreadsheet-RL-4B.Q4_K_M.gguf",
21
+ "Q5_K_S · 3.2 GB": "Spreadsheet-RL-4B.Q5_K_S.gguf",
22
+ "Q5_K_M · 3.3 GB": "Spreadsheet-RL-4B.Q5_K_M.gguf",
23
+ "Q6_K · 3.7 GB · very good quality": "Spreadsheet-RL-4B.Q6_K.gguf",
24
+ "Q8_0 · 4.8 GB · best quality": "Spreadsheet-RL-4B.Q8_0.gguf",
25
+ "f16 · 8.9 GB": "Spreadsheet-RL-4B.f16.gguf",
26
+ }
27
+
28
+ model = None
29
+ tokenizer = None
30
+ active_quant = None
31
+
32
+
33
+ def download_quant(quantization: str) -> None:
34
+ hf_hub_download(repo_id=MODEL_REPO, filename=QUANT_FILES[quantization])
35
+
36
+
37
+ def file_to_text(file_path: str | None) -> str:
38
+ if file_path is None:
39
+ return ""
40
+
41
+ path = Path(file_path)
42
+ suffix = path.suffix.lower()
43
+
44
+ if suffix in {".xlsx", ".xls"}:
45
+ sheets = pd.read_excel(path, sheet_name=None)
46
+ return "\n\n".join(
47
+ f"## Sheet: {sheet_name}\n{frame.to_csv(index=False)}"
48
+ for sheet_name, frame in sheets.items()
49
+ )
50
+
51
+ if suffix == ".csv":
52
+ return pd.read_csv(path).to_csv(index=False)
53
+
54
+ if suffix == ".tsv":
55
+ return pd.read_csv(path, sep="\t").to_csv(index=False)
56
+
57
+ return path.read_text(encoding="utf-8")
58
+
59
+
60
+ @spaces.GPU(duration=120)
61
+ def generate(
62
+ system_prompt: str,
63
+ user_prompt: str,
64
+ attachment: str | None,
65
+ quantization: str,
66
+ ) -> str:
67
+ global active_quant, model, tokenizer
68
+
69
+ quant_file = QUANT_FILES[quantization]
70
+ if active_quant != quantization:
71
+ model = None
72
+ tokenizer = None
73
+ active_quant = None
74
+ collect()
75
+ torch.cuda.empty_cache()
76
+
77
+ tokenizer = AutoTokenizer.from_pretrained(
78
+ MODEL_REPO,
79
+ gguf_file=quant_file,
80
+ )
81
+ model = AutoModelForCausalLM.from_pretrained(
82
+ MODEL_REPO,
83
+ gguf_file=quant_file,
84
+ dtype=torch.bfloat16,
85
+ device_map="cuda",
86
+ )
87
+ active_quant = quantization
88
+
89
+ attachment_text = file_to_text(attachment)
90
+ user_content = user_prompt
91
+ if attachment_text:
92
+ user_content = f"{user_prompt}\n\n<attachment>\n{attachment_text}\n</attachment>"
93
+
94
+ messages = [
95
+ {"role": "system", "content": system_prompt},
96
+ {"role": "user", "content": user_content},
97
+ ]
98
+ inputs = tokenizer.apply_chat_template(
99
+ messages,
100
+ add_generation_prompt=True,
101
+ return_tensors="pt",
102
+ ).to(model.device)
103
+
104
+ with torch.inference_mode():
105
+ generated = model.generate(
106
+ inputs,
107
+ max_new_tokens=512,
108
+ do_sample=True,
109
+ temperature=0.6,
110
+ top_p=0.95,
111
+ top_k=20,
112
+ )
113
+
114
+ return tokenizer.decode(
115
+ generated[0, inputs.shape[-1] :],
116
+ skip_special_tokens=True,
117
+ )
118
+
119
+
120
+ CSS = """
121
+ .gradio-container { max-width: 1180px !important; }
122
+ .agent-panel { border: 2px dashed #79b5ce; border-radius: 18px; padding: 8px; }
123
+ .output-panel { border: 2px dashed #f0aeb7; border-radius: 18px; padding: 8px; }
124
+ """
125
+
126
+ with gr.Blocks(css=CSS, title="Spreadsheet Data Agent") as demo:
127
+ gr.Markdown(
128
+ """
129
+ # Spreadsheet Data Agent
130
+ Send instructions and optional file context to Spreadsheet-RL-4B. This first
131
+ inference surface implements the prompt-and-file entry point from the agent diagram.
132
+ """
133
+ )
134
+
135
+ with gr.Row():
136
+ with gr.Column(scale=1, elem_classes="agent-panel"):
137
+ gr.Markdown("### RL data input")
138
+ system_prompt = gr.Textbox(
139
+ label="System prompt",
140
+ value=(
141
+ "You are a spreadsheet reasoning assistant. Inspect the supplied "
142
+ "spreadsheet or text context and answer the user's request precisely."
143
+ ),
144
+ lines=5,
145
+ )
146
+ user_prompt = gr.Textbox(
147
+ label="User prompt",
148
+ placeholder="Describe the spreadsheet task or ask a question…",
149
+ lines=8,
150
+ )
151
+ attachment = gr.File(
152
+ label="Optional file context",
153
+ file_types=[".txt", ".md", ".json", ".csv", ".tsv", ".xlsx", ".xls"],
154
+ type="filepath",
155
+ )
156
+ quantization = gr.Dropdown(
157
+ choices=list(QUANT_FILES),
158
+ value="Q4_K_M · 2.8 GB · recommended",
159
+ label="Spreadsheet-RL-4B quantization",
160
+ info="Static GGUF quants published by mradermacher; Q4_K_M is the reference recommendation.",
161
+ )
162
+ run = gr.Button("Run inference", variant="primary")
163
+
164
+ with gr.Column(scale=1, elem_classes="output-panel"):
165
+ gr.Markdown("### Agent response")
166
+ response = gr.Textbox(
167
+ label="Generated text",
168
+ lines=28,
169
+ buttons=["copy"],
170
+ )
171
+
172
+ run.click(
173
+ fn=download_quant,
174
+ inputs=quantization,
175
+ outputs=None,
176
+ show_progress="full",
177
+ ).then(
178
+ fn=generate,
179
+ inputs=[system_prompt, user_prompt, attachment, quantization],
180
+ outputs=response,
181
+ api_name="generate",
182
+ show_progress="full",
183
+ )
184
+
185
+ demo.queue().launch()
mise.toml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ [tools]
2
+ powershell = "7"
3
+ python = "3.12"
4
+ uv = "latest"
5
+
6
+ [env]
7
+ UV_LINK_MODE="copy"
pyproject.toml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "spreadsheetapp"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12.10"
7
+ dependencies = [
8
+ "accelerate>=1.14.0",
9
+ "gguf>=0.19.0",
10
+ "huggingface-hub>=1.27.0",
11
+ "openpyxl>=3.1.5",
12
+ "pandas>=3.0.5",
13
+ "spaces>=0.51.1",
14
+ "torch==2.11.0",
15
+ "transformers==5.15.0",
16
+ "xlrd>=2.0.2",
17
+ ]
18
+
19
+ [tool.uv.sources]
20
+ torch = { index = "pytorch-cu130" }
21
+
22
+ [[tool.uv.index]]
23
+ name = "pytorch-cu130"
24
+ url = "https://download.pytorch.org/whl/cu130"
25
+ explicit = true
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ accelerate
2
+ gguf
3
+ huggingface-hub
4
+ openpyxl
5
+ pandas
6
+ spaces
7
+ torch==2.11.0
8
+ transformers==5.15.0
9
+ xlrd