Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -35,13 +35,13 @@ if not YUNWU_API_KEY:
|
|
| 35 |
"请在 Hugging Face Space 的 Settings → Variables and secrets 中添加 YUNWU_API_KEY。"
|
| 36 |
)
|
| 37 |
|
| 38 |
-
#
|
| 39 |
client = OpenAI(
|
| 40 |
api_key=YUNWU_API_KEY,
|
| 41 |
base_url="https://yunwu.ai/v1",
|
| 42 |
)
|
| 43 |
|
| 44 |
-
# 便宜模型:用于检索、
|
| 45 |
MODEL_CHEAP = os.environ.get("MODEL_CHEAP", "deepseek-chat")
|
| 46 |
|
| 47 |
# 强模型:用于核心学术解释、annotation 设计、严肃 paraphrase
|
|
@@ -107,20 +107,21 @@ def extract_pdf_snippet(pdf_path: Optional[str], max_chars: int = 4000) -> str:
|
|
| 107 |
# 4. 主逻辑函数:多模型协作的图表解释工作流
|
| 108 |
# =========================
|
| 109 |
|
| 110 |
-
def chart_assistant_workflow(image, keywords, style, pdf_path):
|
| 111 |
"""
|
| 112 |
主函数:
|
| 113 |
-
1. 结合论文说明图表
|
| 114 |
-
2. 给出如何 annotate 图表的建议(
|
| 115 |
-
3.
|
| 116 |
"""
|
| 117 |
|
| 118 |
if image is None:
|
| 119 |
return (
|
| 120 |
None,
|
| 121 |
-
"",
|
| 122 |
-
"",
|
| 123 |
-
"",
|
|
|
|
| 124 |
)
|
| 125 |
|
| 126 |
# -------- Step 0:Vision 粗描述 + PDF 上下文 ----------
|
|
@@ -128,7 +129,7 @@ def chart_assistant_workflow(image, keywords, style, pdf_path):
|
|
| 128 |
pdf_context = extract_pdf_snippet(pdf_path)
|
| 129 |
kw_text = (keywords or "").strip()
|
| 130 |
|
| 131 |
-
# ========== Step 1:图表含义解释(英文
|
| 132 |
|
| 133 |
# 1.1 强模型生成英文解释(基于图 + 论文)
|
| 134 |
explain_en_prompt = f"""
|
|
@@ -160,8 +161,11 @@ Write in clear, formal academic English, suitable for a Results-style explanatio
|
|
| 160 |
max_tokens=350,
|
| 161 |
)
|
| 162 |
|
| 163 |
-
# 1.2
|
| 164 |
-
|
|
|
|
|
|
|
|
|
|
| 165 |
你是一名科学写作助手。请将下面这段英文图表解释翻译成自然、清晰的中文,适合大学生在课堂讲解或书面作业中使用。
|
| 166 |
|
| 167 |
要求:
|
|
@@ -173,16 +177,16 @@ Write in clear, formal academic English, suitable for a Results-style explanatio
|
|
| 173 |
|
| 174 |
请给出中文译文:
|
| 175 |
"""
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
|
| 182 |
-
# ========== Step 2:给出 annotate 建议(
|
| 183 |
|
| 184 |
annotate_prompt = f"""
|
| 185 |
-
You are designing annotation suggestions for a scientific figure that compares treatments in
|
| 186 |
|
| 187 |
Here is an English explanation of what the figure shows:
|
| 188 |
\"\"\"{explanation_en}\"\"\"
|
|
@@ -196,49 +200,44 @@ User keywords:
|
|
| 196 |
Task:
|
| 197 |
Propose how a student should annotate this figure to make it easier to understand in a presentation or assignment.
|
| 198 |
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
2) Then, in CHINESE, give对应的 3–5 条标注建议,语言简洁、适合直接告诉同学「你应该如何在图上标注」。
|
| 205 |
|
| 206 |
-
Return
|
| 207 |
-
|
| 208 |
-
ANNOTATION_EN:
|
| 209 |
-
- ...
|
| 210 |
-
|
| 211 |
-
ANNOTATION_ZH:
|
| 212 |
-
- ...
|
| 213 |
"""
|
| 214 |
-
|
| 215 |
annotate_prompt,
|
| 216 |
model=MODEL_STRONG,
|
| 217 |
-
max_tokens=
|
| 218 |
)
|
| 219 |
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
annotation_zh = ""
|
| 223 |
-
text_ann = annotation_raw
|
| 224 |
-
|
| 225 |
-
if "ANNOTATION_EN:" in text_ann:
|
| 226 |
-
after_en = text_ann.split("ANNOTATION_EN:", 1)[1]
|
| 227 |
else:
|
| 228 |
-
|
|
|
|
| 229 |
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
else:
|
| 233 |
-
annotation_en, annotation_zh = after_en, ""
|
| 234 |
|
| 235 |
-
|
| 236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
# ========== Step 3:根据风格 paraphrase 论文解释 ==========
|
| 239 |
-
#
|
| 240 |
|
| 241 |
-
# 3.1 便宜模型从论文中抽一段「
|
| 242 |
paper_exp_prompt = f"""
|
| 243 |
You are given part of a scientific paper and a description of a figure.
|
| 244 |
|
|
@@ -299,15 +298,37 @@ Give ONLY the rewritten paragraph in English.
|
|
| 299 |
max_tokens=320,
|
| 300 |
)
|
| 301 |
|
| 302 |
-
# 3.3
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
|
|
|
|
|
|
| 309 |
|
| 310 |
-
|
| 311 |
你是一名科学写作助手。
|
| 312 |
|
| 313 |
下面是一段英文解释,是针对某个图表、已经按「{style_label_zh}」改写过的版本:
|
|
@@ -320,31 +341,25 @@ Give ONLY the rewritten paragraph in English.
|
|
| 320 |
|
| 321 |
请直接给出中文版本:
|
| 322 |
"""
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
|
| 329 |
# ========== 最终返回给 Gradio 的输出 ==========
|
| 330 |
# 1. 原图
|
| 331 |
-
# 2.
|
| 332 |
-
# 3.
|
| 333 |
-
# 4.
|
| 334 |
-
# 5.
|
| 335 |
-
# 6. Step 3 原论文风格英文解释
|
| 336 |
-
# 7. Step 3 按风格改写英文解释
|
| 337 |
-
# 8. Step 3 按风格改写的中文解释
|
| 338 |
|
| 339 |
return (
|
| 340 |
image,
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
paper_explanation_en,
|
| 346 |
-
styled_explanation_en,
|
| 347 |
-
styled_explanation_zh,
|
| 348 |
)
|
| 349 |
|
| 350 |
|
|
@@ -353,81 +368,73 @@ Give ONLY the rewritten paragraph in English.
|
|
| 353 |
# =========================
|
| 354 |
|
| 355 |
with gr.Blocks() as demo:
|
| 356 |
-
gr.Markdown("## ChartSmith v3 –
|
| 357 |
|
| 358 |
with gr.Row():
|
| 359 |
# 左侧:输入
|
| 360 |
with gr.Column():
|
| 361 |
img_in = gr.Image(
|
| 362 |
type="pil",
|
| 363 |
-
label="
|
| 364 |
)
|
| 365 |
|
| 366 |
keywords = gr.Textbox(
|
| 367 |
-
label="
|
| 368 |
placeholder="bleaching, coral, temperature, CO2",
|
| 369 |
)
|
| 370 |
|
| 371 |
style = gr.Radio(
|
| 372 |
choices=["formal", "fluency", "simple"],
|
| 373 |
value="formal",
|
| 374 |
-
label="Step 3:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 375 |
)
|
| 376 |
|
| 377 |
pdf_in = gr.File(
|
| 378 |
-
label="
|
| 379 |
type="filepath"
|
| 380 |
)
|
| 381 |
|
| 382 |
-
run_btn = gr.Button("
|
| 383 |
|
| 384 |
# 右侧:输出
|
| 385 |
with gr.Column():
|
| 386 |
-
orig_img = gr.Image(label="
|
| 387 |
|
| 388 |
-
|
| 389 |
-
label="Step
|
| 390 |
-
lines=6
|
| 391 |
-
)
|
| 392 |
-
explain_zh_box = gr.Textbox(
|
| 393 |
-
label="Step 1B: 图表含义解释(中文)",
|
| 394 |
lines=6
|
| 395 |
)
|
| 396 |
|
| 397 |
-
|
| 398 |
-
label="Step
|
| 399 |
-
lines=6
|
| 400 |
-
)
|
| 401 |
-
ann_zh_box = gr.Textbox(
|
| 402 |
-
label="Step 2B: 图表标注建议(中文)",
|
| 403 |
lines=6
|
| 404 |
)
|
| 405 |
|
| 406 |
paper_exp_box = gr.Textbox(
|
| 407 |
-
label="Step 3A:
|
| 408 |
-
lines=6
|
| 409 |
-
)
|
| 410 |
-
styled_en_box = gr.Textbox(
|
| 411 |
-
label="Step 3B: 按所选风格改写后的英文解释",
|
| 412 |
lines=6
|
| 413 |
)
|
| 414 |
-
|
| 415 |
-
|
|
|
|
| 416 |
lines=6
|
| 417 |
)
|
| 418 |
|
| 419 |
run_btn.click(
|
| 420 |
chart_assistant_workflow,
|
| 421 |
-
inputs=[img_in, keywords, style, pdf_in],
|
| 422 |
outputs=[
|
| 423 |
orig_img,
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
ann_en_box,
|
| 427 |
-
ann_zh_box,
|
| 428 |
paper_exp_box,
|
| 429 |
-
|
| 430 |
-
styled_zh_box,
|
| 431 |
],
|
| 432 |
)
|
| 433 |
|
|
|
|
| 35 |
"请在 Hugging Face Space 的 Settings → Variables and secrets 中添加 YUNWU_API_KEY。"
|
| 36 |
)
|
| 37 |
|
| 38 |
+
# 云雾的 OpenAI 兼容地址
|
| 39 |
client = OpenAI(
|
| 40 |
api_key=YUNWU_API_KEY,
|
| 41 |
base_url="https://yunwu.ai/v1",
|
| 42 |
)
|
| 43 |
|
| 44 |
+
# 便宜模型:用于检索、翻译、粗 paraphrase
|
| 45 |
MODEL_CHEAP = os.environ.get("MODEL_CHEAP", "deepseek-chat")
|
| 46 |
|
| 47 |
# 强模型:用于核心学术解释、annotation 设计、严肃 paraphrase
|
|
|
|
| 107 |
# 4. 主逻辑函数:多模型协作的图表解释工作流
|
| 108 |
# =========================
|
| 109 |
|
| 110 |
+
def chart_assistant_workflow(image, keywords, style, language, pdf_path):
|
| 111 |
"""
|
| 112 |
主函数:
|
| 113 |
+
1. 结合论文说明图表含义(根据 language 输出 English 或 中文)
|
| 114 |
+
2. 给出如何 annotate 图表的建议(同样根据 language)
|
| 115 |
+
3. 根据 style(formal / fluency / simple)paraphrase 论文解释(同样根据 language)
|
| 116 |
"""
|
| 117 |
|
| 118 |
if image is None:
|
| 119 |
return (
|
| 120 |
None,
|
| 121 |
+
"", # explanation_out
|
| 122 |
+
"", # annotation_out
|
| 123 |
+
"", # paper_explanation_out
|
| 124 |
+
"", # styled_explanation_out
|
| 125 |
)
|
| 126 |
|
| 127 |
# -------- Step 0:Vision 粗描述 + PDF 上下文 ----------
|
|
|
|
| 129 |
pdf_context = extract_pdf_snippet(pdf_path)
|
| 130 |
kw_text = (keywords or "").strip()
|
| 131 |
|
| 132 |
+
# ========== Step 1:图表含义解释(英文为母版,按 language 决定最终输出) ==========
|
| 133 |
|
| 134 |
# 1.1 强模型生成英文解释(基于图 + 论文)
|
| 135 |
explain_en_prompt = f"""
|
|
|
|
| 161 |
max_tokens=350,
|
| 162 |
)
|
| 163 |
|
| 164 |
+
# 1.2 按语言选择输出
|
| 165 |
+
if language == "English":
|
| 166 |
+
explanation_out = explanation_en
|
| 167 |
+
else:
|
| 168 |
+
explain_zh_prompt = f"""
|
| 169 |
你是一名科学写作助手。请将下面这段英文图表解释翻译成自然、清晰的中文,适合大学生在课堂讲解或书面作业中使用。
|
| 170 |
|
| 171 |
要求:
|
|
|
|
| 177 |
|
| 178 |
请给出中文译文:
|
| 179 |
"""
|
| 180 |
+
explanation_out = call_llm(
|
| 181 |
+
explain_zh_prompt,
|
| 182 |
+
model=MODEL_CHEAP,
|
| 183 |
+
max_tokens=400,
|
| 184 |
+
)
|
| 185 |
|
| 186 |
+
# ========== Step 2:给出 annotate 建议(根据 language 输出) ==========
|
| 187 |
|
| 188 |
annotate_prompt = f"""
|
| 189 |
+
You are designing annotation suggestions for a scientific figure that compares treatments in an experiment.
|
| 190 |
|
| 191 |
Here is an English explanation of what the figure shows:
|
| 192 |
\"\"\"{explanation_en}\"\"\"
|
|
|
|
| 200 |
Task:
|
| 201 |
Propose how a student should annotate this figure to make it easier to understand in a presentation or assignment.
|
| 202 |
|
| 203 |
+
Give 3–5 bullet-point suggestions in ENGLISH. Each bullet should follow this pattern:
|
| 204 |
+
- what to highlight (e.g. "the bar with the highest bleaching under high temperature"),
|
| 205 |
+
- how to annotate it (arrow / circle / label),
|
| 206 |
+
- why (e.g. "this is the strongest response and supports the main conclusion").
|
|
|
|
|
|
|
| 207 |
|
| 208 |
+
Return only the bullet list in English.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
"""
|
| 210 |
+
annotation_en = call_llm(
|
| 211 |
annotate_prompt,
|
| 212 |
model=MODEL_STRONG,
|
| 213 |
+
max_tokens=450,
|
| 214 |
)
|
| 215 |
|
| 216 |
+
if language == "English":
|
| 217 |
+
annotation_out = annotation_en
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
else:
|
| 219 |
+
annotate_zh_prompt = f"""
|
| 220 |
+
你是一名科学可视化助手。
|
| 221 |
|
| 222 |
+
下面是一组关于“如何在图表上添加标注”的英文建议(每条都是 bullet):
|
| 223 |
+
\"\"\"{annotation_en}\"\"\"
|
|
|
|
|
|
|
| 224 |
|
| 225 |
+
请将这些建议转写为中文 bullet list,要求:
|
| 226 |
+
- 每条都说明「标注什么、如何标注、为什么要这样标注」
|
| 227 |
+
- 语言简洁、适合给学生作为操作说明
|
| 228 |
+
|
| 229 |
+
请直接给出中文 bullet 列表:
|
| 230 |
+
"""
|
| 231 |
+
annotation_out = call_llm(
|
| 232 |
+
annotate_zh_prompt,
|
| 233 |
+
model=MODEL_CHEAP,
|
| 234 |
+
max_tokens=450,
|
| 235 |
+
)
|
| 236 |
|
| 237 |
# ========== Step 3:根据风格 paraphrase 论文解释 ==========
|
| 238 |
+
# 先得到“论文风格英文解释”,再按 style 改写,最后按 language 选择输出
|
| 239 |
|
| 240 |
+
# 3.1 便宜模型从论文中抽一段「论文风格」的英文说明
|
| 241 |
paper_exp_prompt = f"""
|
| 242 |
You are given part of a scientific paper and a description of a figure.
|
| 243 |
|
|
|
|
| 298 |
max_tokens=320,
|
| 299 |
)
|
| 300 |
|
| 301 |
+
# 3.3 按语言输出 paper-style 和 styled 版本
|
| 302 |
+
|
| 303 |
+
if language == "English":
|
| 304 |
+
paper_explanation_out = paper_explanation_en
|
| 305 |
+
styled_explanation_out = styled_explanation_en
|
| 306 |
+
else:
|
| 307 |
+
style_label_zh = {
|
| 308 |
+
"formal": "正式学术风格",
|
| 309 |
+
"fluency": "口语讲解风格",
|
| 310 |
+
"simple": "简明易懂风格",
|
| 311 |
+
}.get(style, "简明易懂风格")
|
| 312 |
+
|
| 313 |
+
paper_zh_prompt = f"""
|
| 314 |
+
你是一名科学写作助手。
|
| 315 |
+
|
| 316 |
+
下面是一段英文解释,是「论文风格」的图表说明:
|
| 317 |
+
\"\"\"{paper_explanation_en}\"\"\"
|
| 318 |
+
|
| 319 |
+
请将这段英文翻译为中文:
|
| 320 |
+
- 保持学术论文 Results 段落的大致风格
|
| 321 |
+
- 保留科学含义,不添加论文里没有的信息
|
| 322 |
|
| 323 |
+
请直接给出中文版本:
|
| 324 |
+
"""
|
| 325 |
+
paper_explanation_out = call_llm(
|
| 326 |
+
paper_zh_prompt,
|
| 327 |
+
model=MODEL_CHEAP,
|
| 328 |
+
max_tokens=320,
|
| 329 |
+
)
|
| 330 |
|
| 331 |
+
styled_zh_prompt = f"""
|
| 332 |
你是一名科学写作助手。
|
| 333 |
|
| 334 |
下面是一段英文解释,是针对某个图表、已经按「{style_label_zh}」改写过的版本:
|
|
|
|
| 341 |
|
| 342 |
请直接给出中文版本:
|
| 343 |
"""
|
| 344 |
+
styled_explanation_out = call_llm(
|
| 345 |
+
styled_zh_prompt,
|
| 346 |
+
model=MODEL_CHEAP,
|
| 347 |
+
max_tokens=350,
|
| 348 |
+
)
|
| 349 |
|
| 350 |
# ========== 最终返回给 Gradio 的输出 ==========
|
| 351 |
# 1. 原图
|
| 352 |
+
# 2. 图表含义解释(当前语言)
|
| 353 |
+
# 3. Annotation 建议(当前语言)
|
| 354 |
+
# 4. 论文风格解释(当前语言)
|
| 355 |
+
# 5. 按 style 改写后的解释(当前语言)
|
|
|
|
|
|
|
|
|
|
| 356 |
|
| 357 |
return (
|
| 358 |
image,
|
| 359 |
+
explanation_out,
|
| 360 |
+
annotation_out,
|
| 361 |
+
paper_explanation_out,
|
| 362 |
+
styled_explanation_out,
|
|
|
|
|
|
|
|
|
|
| 363 |
)
|
| 364 |
|
| 365 |
|
|
|
|
| 368 |
# =========================
|
| 369 |
|
| 370 |
with gr.Blocks() as demo:
|
| 371 |
+
gr.Markdown("## ChartSmith v3 – Multi-model Chart Explanation Assistant")
|
| 372 |
|
| 373 |
with gr.Row():
|
| 374 |
# 左侧:输入
|
| 375 |
with gr.Column():
|
| 376 |
img_in = gr.Image(
|
| 377 |
type="pil",
|
| 378 |
+
label="Upload a figure from the paper"
|
| 379 |
)
|
| 380 |
|
| 381 |
keywords = gr.Textbox(
|
| 382 |
+
label="Figure keywords / variables (English, comma-separated, e.g. bleaching, coral, temperature, CO2)",
|
| 383 |
placeholder="bleaching, coral, temperature, CO2",
|
| 384 |
)
|
| 385 |
|
| 386 |
style = gr.Radio(
|
| 387 |
choices=["formal", "fluency", "simple"],
|
| 388 |
value="formal",
|
| 389 |
+
label="Step 3: Explanation style"
|
| 390 |
+
)
|
| 391 |
+
|
| 392 |
+
language = gr.Radio(
|
| 393 |
+
choices=["English", "中文"],
|
| 394 |
+
value="English",
|
| 395 |
+
label="Output language"
|
| 396 |
)
|
| 397 |
|
| 398 |
pdf_in = gr.File(
|
| 399 |
+
label="Upload the paper PDF (for context)",
|
| 400 |
type="filepath"
|
| 401 |
)
|
| 402 |
|
| 403 |
+
run_btn = gr.Button("Run workflow", variant="primary")
|
| 404 |
|
| 405 |
# 右侧:输出
|
| 406 |
with gr.Column():
|
| 407 |
+
orig_img = gr.Image(label="Figure preview")
|
| 408 |
|
| 409 |
+
explain_box = gr.Textbox(
|
| 410 |
+
label="Step 1: Explanation of what the figure shows",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
lines=6
|
| 412 |
)
|
| 413 |
|
| 414 |
+
ann_box = gr.Textbox(
|
| 415 |
+
label="Step 2: Suggestions for annotating the figure",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 416 |
lines=6
|
| 417 |
)
|
| 418 |
|
| 419 |
paper_exp_box = gr.Textbox(
|
| 420 |
+
label="Step 3A: Paper-style explanation of the figure",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 421 |
lines=6
|
| 422 |
)
|
| 423 |
+
|
| 424 |
+
styled_exp_box = gr.Textbox(
|
| 425 |
+
label="Step 3B: Style-adjusted explanation (for report / talk / simple notes)",
|
| 426 |
lines=6
|
| 427 |
)
|
| 428 |
|
| 429 |
run_btn.click(
|
| 430 |
chart_assistant_workflow,
|
| 431 |
+
inputs=[img_in, keywords, style, language, pdf_in],
|
| 432 |
outputs=[
|
| 433 |
orig_img,
|
| 434 |
+
explain_box,
|
| 435 |
+
ann_box,
|
|
|
|
|
|
|
| 436 |
paper_exp_box,
|
| 437 |
+
styled_exp_box,
|
|
|
|
| 438 |
],
|
| 439 |
)
|
| 440 |
|