File size: 3,352 Bytes
72b3f03
ff31f1e
72b3f03
 
 
ff31f1e
f2604be
85f1538
72b3f03
 
 
 
 
f2604be
72b3f03
 
 
 
 
 
 
 
 
85f1538
72b3f03
 
 
 
 
 
 
 
 
 
f2604be
72b3f03
 
f2604be
72b3f03
 
 
ff31f1e
72b3f03
 
 
 
 
 
 
 
85f1538
72b3f03
 
 
 
 
f2604be
d778a89
 
 
 
f2604be
d778a89
 
72b3f03
 
 
 
 
 
 
 
f2604be
72b3f03
 
f2604be
72b3f03
 
 
 
 
 
 
 
85f1538
72b3f03
 
 
 
f2604be
72b3f03
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
import gradio as gr
import fitz
import docx
from huggingface_hub import InferenceClient

# 1. 引擎配置:Qwen-2.5-72B-Instruct (全能稳定版)
model_id = "Qwen/Qwen2.5-72B-Instruct"
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)
            return "".join([page.get_text() for page in doc])[: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,因为 API 模式下它反而会因超时导致报错
def chat_fn(message, history):
    clean_messages = []
    clean_messages.append({"role": "system", "content": "You are a professional patent and legal translation expert. Provide accurate translations."})
    
    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
        )
        
        for msg in stream:
            if hasattr(msg, 'choices') and len(msg.choices) > 0:
                delta_content = msg.choices[0].delta.content
                if delta_content:
                    response += str(delta_content)
                    yield response
        
        if response:
            yield response + "\n\n---\n> **OpenIPOS MegaNode | Qwen-2.5 专业算力出口**"
            
    except Exception as e:
        yield f"⚠️ 算力调度提示: {str(e)}。由于翻译长文档耗时较长,请分段进行或刷新重试。"

# 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;">全球顶尖中文全能算力出口 (Qwen-2.5-72B)</p>
            </div>
        </div>
    """)
    gr.ChatInterface(chat_fn, multimodal=True)
    gr.Markdown("© 2026 OpenIPOS Global Limited. 算力驱动:Novita API Cluster")

demo.launch(theme=gr.themes.Soft())