OpenIPOS's picture
Update app.py
d33a38e verified
Raw History Blame Contribute Delete
4.23 kB
import os
import gradio as gr
import spaces
import fitz
import docx
from huggingface_hub import InferenceClient
# 1. 引擎配置:DeepSeek-V3.2-Exp (685B 逻辑核弹)
model_id = "deepseek-ai/DeepSeek-V3.2-Exp"
hf_token = os.getenv("HF_TOKEN")
# 强制授权连接
client = InferenceClient(
model=model_id,
token=hf_token,
headers={"Authorization": f"Bearer {hf_token}"} if hf_token else None
)
def extract_text(file_path):
if not file_path: return ""
try:
ext = str(file_path).lower()
if ext.endswith(".pdf"):
doc = fitz.open(file_path)
text = "".join([page.get_text() for page in doc])
doc.close()
return text[:15000]
elif ext.endswith(".docx"):
doc = docx.Document(file_path)
return "\n".join([p.text for p in doc.paragraphs])[:15000]
elif ext.endswith(".txt"):
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
return f.read()[:15000]
return ""
except:
return ""
@spaces.GPU(duration=60)
def chat_fn(message, history):
# 彻底压扁历史记录,确保 DeepSeek 接收的是纯字符串
clean_messages = []
# 增加一个系统提示词,强制模型进入“专业翻译/分析”模式
clean_messages.append({"role": "system", "content": "You are a professional patent and legal expert assistant. Analyze and translate documents with high precision."})
for turn in history:
clean_messages.append({"role": turn["role"], "content": str(turn["content"])})
prompt_text = message.get("text", "")
files = message.get("files", [])
if files:
f = files[0]
file_path = f.get("path") if isinstance(f, dict) else f
context = extract_text(file_path)
if context:
prompt_text = f"【参考文档背景】:\n{context}\n\n【指令】: {prompt_text}"
clean_messages.append({"role": "user", "content": prompt_text})
response = ""
try:
# 增加流式输出的稳定性控制
stream = client.chat_completion(
clean_messages,
max_tokens=4096,
stream=True,
temperature=0.4, # 降低温度,增加输出的确定性和速度
top_p=0.9
)
for msg in stream:
if hasattr(msg, 'choices') and len(msg.choices) > 0:
delta_content = msg.choices[0].delta.content
if delta_content:
# 彻底清洗 JSON 列表格式数据
if isinstance(delta_content, list):
content = "".join([item.get("text", "") for item in delta_content if isinstance(item, dict)])
elif isinstance(delta_content, dict):
content = delta_content.get("text", "")
else:
content = str(delta_content)
response += content
yield response
if not response:
yield "⚠️ 当前算力节点极其繁忙,请尝试重新发送指令或稍微等待几分钟。"
else:
yield response + "\n\n---\n> **Powered by OpenIPOS Global 算力节点 | 访问 api.openipos.com 获取企业级私有部署**"
except Exception as e:
yield f"⚠️ 调度波动: {str(e)}。由于 DeepSeek-R1 级别模型访问量巨大,请刷新页面重试。"
# 3. 统一品牌装修
with gr.Blocks(fill_height=True) as demo:
gr.HTML("""
<div style="display: flex; align-items: center; gap: 20px; padding: 10px;">
<img src="https://s3.bmp.ovh/2026/03/30/rIAGKg0O.png" style="height: 60px; width: auto;">
<div>
<h1 style="margin: 0; font-size: 24px;">OpenIPOS MegaNode</h1>
<p style="margin: 0; color: #666;">全球领先逻辑推理节点 (DeepSeek-R1 级别算力)</p>
</div>
</div>
""")
gr.ChatInterface(chat_fn, multimodal=True)
gr.Markdown("© 2026 OpenIPOS Global Limited. 算力驱动:Novita API Cluster")
# 设置默认主题
demo.launch(theme=gr.themes.Soft())