DYDYLAN commited on
Commit
ae07758
Β·
verified Β·
1 Parent(s): 49e9bd8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +9 -55
app.py CHANGED
@@ -6,38 +6,25 @@ from openai import OpenAI
6
  from pypdf import PdfReader
7
 
8
 
9
- # =========================
10
- # 1. Device & local vision captioner
11
- # =========================
12
  device = "cuda" if torch.cuda.is_available() else "cpu"
13
 
14
- # Lightweight image->text captioner for rough visual grounding
15
  vision_pipe = pipeline(
16
  "image-to-text",
17
  model="nlpconnect/vit-gpt2-image-captioning",
18
  device=0 if device == "cuda" else -1
19
  )
20
 
21
- # =========================
22
- # 2. Yunwu / OpenAI-compatible API client
23
- # =========================
24
- YUNWU_API_KEY = os.environ.get("YUNWU_API_KEY")
25
- if not YUNWU_API_KEY:
26
- raise RuntimeError(
27
- "YUNWU_API_KEY not set. Add it in HF Space: Settings β†’ Variables and secrets."
28
- )
29
 
30
  client = OpenAI(
31
- api_key=YUNWU_API_KEY,
32
- base_url="https://yunwu.ai/v1" # Yunwu OpenAI-compatible endpoint
33
  )
34
 
35
- def call_llm(
36
- prompt: str,
37
- model: str = "deepseek-chat",
38
- temperature: float = 0.2,
39
- max_tokens: int = 512
40
- ) -> str:
41
  resp = client.chat.completions.create(
42
  model=model,
43
  messages=[
@@ -56,15 +43,12 @@ def call_llm(
56
  return resp.choices[0].message.content.strip()
57
 
58
 
59
- # =========================
60
- # 3. Utils: PDF snippet
61
- # =========================
62
- def extract_pdf_snippet(pdf_path: str | None, max_chars: int = 2500) -> str:
63
  if not pdf_path:
64
  return ""
65
  try:
66
  reader = PdfReader(pdf_path)
67
- texts: list[str] = []
68
  for page in reader.pages:
69
  txt = page.extract_text() or ""
70
  texts.append(txt)
@@ -76,31 +60,13 @@ def extract_pdf_snippet(pdf_path: str | None, max_chars: int = 2500) -> str:
76
  return ""
77
 
78
 
79
- # =========================
80
- # 4. Main workflow
81
- # =========================
82
  def analyze_figure(image, style, pdf_path):
83
- """
84
- Outputs:
85
- - Step 1: Paper-style explanation of what the figure shows (English)
86
- - Step 2: Human-like suggestions for annotating the figure (English)
87
- - Step 3: Plain-language explanation for presentations/assignments,
88
- adapted to style (formal / fluency / simple)
89
- """
90
-
91
  if image is None:
92
  return None, "Please upload a figure first.", "", ""
93
 
94
- # Step 0: rough visual caption
95
  vision_raw = vision_pipe(image)[0]["generated_text"]
96
-
97
- # Paper context
98
  pdf_context = extract_pdf_snippet(pdf_path)
99
 
100
- # -------------------------
101
- # Step 1: Figure meaning (paper-style)
102
- # Use a stronger model if you like, e.g. "gpt-5.1" on Yunwu.
103
- # -------------------------
104
  step1_prompt = f"""
105
  You are looking at a scientific figure from a paper.
106
 
@@ -121,10 +87,6 @@ Write in formal academic English, but keep it readable.
121
  """
122
  step1_text = call_llm(step1_prompt, model="deepseek-chat", max_tokens=420)
123
 
124
- # -------------------------
125
- # Step 2: Annotation suggestions (natural, not β€œAI-ish”)
126
- # Keep it short, practical, no bold/markdown.
127
- # -------------------------
128
  step2_prompt = f"""
129
  You are helping a student annotate this scientific figure for a presentation.
130
 
@@ -142,13 +104,8 @@ Constraints:
142
  - Focus on labels, arrows, callouts, grouping, legend clarity, and highlighting key contrasts.
143
  """
144
  step2_text = call_llm(step2_prompt, model="deepseek-chat", temperature=0.4, max_tokens=260)
145
-
146
- # Light cleanup to remove accidental markdown/bold
147
  step2_text = step2_text.replace("**", "").replace("*", "").strip()
148
 
149
- # -------------------------
150
- # Step 3: Plain-language explanation in chosen style
151
- # -------------------------
152
  style_map = {
153
  "formal": "formal but still plain language, suitable for a report",
154
  "fluency": "smooth, narrative, easy to speak aloud in a presentation",
@@ -176,9 +133,6 @@ Now paraphrase/explain the figure in {style_instruction}.
176
  return image, step1_text, step2_text, step3_text
177
 
178
 
179
- # =========================
180
- # 5. Gradio UI
181
- # =========================
182
  with gr.Blocks() as demo:
183
  gr.Markdown("## ChartSmith – AI Figure Explainer (multi-model workflow)")
184
 
 
6
  from pypdf import PdfReader
7
 
8
 
 
 
 
9
  device = "cuda" if torch.cuda.is_available() else "cpu"
10
 
 
11
  vision_pipe = pipeline(
12
  "image-to-text",
13
  model="nlpconnect/vit-gpt2-image-captioning",
14
  device=0 if device == "cuda" else -1
15
  )
16
 
17
+ api_key = os.environ.get("YUNWU_API_KEY")
18
+ if not api_key:
19
+ raise RuntimeError("YUNWU_API_KEY not set in Space secrets.")
 
 
 
 
 
20
 
21
  client = OpenAI(
22
+ api_key=api_key,
23
+ base_url="https://yunwu.ai/v1"
24
  )
25
 
26
+
27
+ def call_llm(prompt, model="deepseek-chat", temperature=0.2, max_tokens=512):
 
 
 
 
28
  resp = client.chat.completions.create(
29
  model=model,
30
  messages=[
 
43
  return resp.choices[0].message.content.strip()
44
 
45
 
46
+ def extract_pdf_snippet(pdf_path, max_chars=2500):
 
 
 
47
  if not pdf_path:
48
  return ""
49
  try:
50
  reader = PdfReader(pdf_path)
51
+ texts = []
52
  for page in reader.pages:
53
  txt = page.extract_text() or ""
54
  texts.append(txt)
 
60
  return ""
61
 
62
 
 
 
 
63
  def analyze_figure(image, style, pdf_path):
 
 
 
 
 
 
 
 
64
  if image is None:
65
  return None, "Please upload a figure first.", "", ""
66
 
 
67
  vision_raw = vision_pipe(image)[0]["generated_text"]
 
 
68
  pdf_context = extract_pdf_snippet(pdf_path)
69
 
 
 
 
 
70
  step1_prompt = f"""
71
  You are looking at a scientific figure from a paper.
72
 
 
87
  """
88
  step1_text = call_llm(step1_prompt, model="deepseek-chat", max_tokens=420)
89
 
 
 
 
 
90
  step2_prompt = f"""
91
  You are helping a student annotate this scientific figure for a presentation.
92
 
 
104
  - Focus on labels, arrows, callouts, grouping, legend clarity, and highlighting key contrasts.
105
  """
106
  step2_text = call_llm(step2_prompt, model="deepseek-chat", temperature=0.4, max_tokens=260)
 
 
107
  step2_text = step2_text.replace("**", "").replace("*", "").strip()
108
 
 
 
 
109
  style_map = {
110
  "formal": "formal but still plain language, suitable for a report",
111
  "fluency": "smooth, narrative, easy to speak aloud in a presentation",
 
133
  return image, step1_text, step2_text, step3_text
134
 
135
 
 
 
 
136
  with gr.Blocks() as demo:
137
  gr.Markdown("## ChartSmith – AI Figure Explainer (multi-model workflow)")
138