7B参数拿下30个世界第一!Hunyuan-MT-7B本地部署教程:腾讯混元开源业界首个翻译集成模型

一、模型介绍

Hunyuan-MT-7B 是腾讯混元团队发布的轻量级翻译模型,参数量仅 70 亿,支持 33 个语种及 5 种民汉语言/方言互译。在国际计算语言学协会(ACL)WMT2025 比赛中拿下 31 个语种比赛中的 30 个第 1 名,表现卓越。模型能精准理解网络用语、古诗、社交对话等,结合语境进行意译,提出了覆盖预训练到集成强化全链条的训练范式。推理速度快,经过腾讯自研 AngelSlim 压缩工具处理后,性能进一步提升 30%。可在多样化硬件环境中部署,成本低。

二、模型部署

快速部署及使用方法,请点击Hunyuan-MT-7B-镜像社区 算家云详细了解

或进入算家云官网 ,参考 "镜像社区"。

基础环境最低配置推荐

环境名称 版本信息
Ubuntu 22.04.4 LTS
Python 3.10
CUDA 12.1
NVIDIA Corporation RTX 4090 *

1.更新基础软件包、配置镜像源

查看系统版本信息

bash 复制代码
#查看系统的版本信息,包括 ID(如 ubuntu、centos 等)、版本号、名称、版本号 ID 等
cat /etc/os-release

配置 apt 国内源

csharp 复制代码
#更新软件列表
apt-get update

这个命令用于更新本地软件包索引。它会从所有配置的源中检索最新的软件包列表信息,但不会安装或升级任何软件包。这是安装新软件包或进行软件包升级之前的推荐步骤,因为它确保了您获取的是最新版本的软件包。

csharp 复制代码
#安装 Vim 编辑器
apt-get install -y vim

这个命令用于安装 Vim 文本编辑器。-y 选项表示自动回答所有的提示为"是",这样在安装过程中就不需要手动确认。Vim 是一个非常强大的文本编辑器,广泛用于编程和配置文件的编辑。

为了安全起见,先备份当前的 sources.list 文件之后,再进行修改:

bash 复制代码
 # 备份现有的软件源列表
cp /etc/apt/sources.list /etc/apt/sources.list.bak

这个命令将当前的 sources.list 文件复制为一个名为 sources.list.bak 的备份文件。这是一个好习惯,因为编辑 sources.list 文件时可能会出错,导致无法安装或更新软件包。有了备份,如果出现问题,您可以轻松地恢复原始的文件。

bash 复制代码
  # 编辑软件源列表文件
vim /etc/apt/sources.list

这个命令使用 Vim 编辑器打开 sources.list 文件,以便您可以编辑它。这个文件包含了 APT(Advanced Package Tool)用于安装和更新软件包的软件源列表。通过编辑这个文件,您可以添加新的软件源、更改现有软件源的优先级或禁用某些软件源。

在 Vim 中,您可以使用方向键来移动光标,

i 键进入插入模式(可以开始编辑文本), Esc 键退出插入模式,

:wq 命令保存更改并退出 Vim,

或 :q! 命令不保存更改并退出 Vim。

编辑 sources.list 文件时,请确保您了解自己在做什么,特别是如果您正在添加新的软件源。错误的源可能会导致软件包安装失败或系统安全问题。如果您不确定,最好先搜索并找到可靠的源信息,或者咨询有经验的 Linux 用户。

配置国内镜像源(阿里云)

"i" 进入编辑模式,将如下内容插入至 sources.list 文件中

arduino 复制代码
deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse

最后,按 "esc" 键退出编辑模式,输入 :wq 命令并按下 "enter" 键便可保存并退出 sources.list 文件

安装常用软件和工具

csharp 复制代码
#更新源列表,输入以下命令:
apt-get update
#更新系统软件包,输入以下命令:
apt-get upgrade
#安装常用软件和工具,输入以下命令:
apt-get -y install vim wget git git-lfs unzip lsof net-tools gcc cmake build-essential

出现以下页面,说明国内 apt 源已替换成功,且能正常安装 apt 软件和工具

2.创建虚拟环境

创建虚拟环境

ini 复制代码
#创建名为Hunyuan-MT的虚拟环境,python版本:3.10
conda create -n Hunyuan-MT python=3.10 -y

激活虚拟环境

复制代码
conda activate Hunyuan-MT

3.克隆项目

创建Qwen-Image文件夹

bash 复制代码
#创建Hunyuan-MT文件夹
mkdir Hunyuan-MT
#进入Hunyuan-MT目录
cd Hunyuan-MT
bash 复制代码
#克隆仓库
git clone https://github.com/Tencent-Hunyuan/Hunyuan-MT.git

4.下载依赖

复制代码
pip install -r requirements.txt

5.模型下载

转到魔塔社区官网下载模型文件:modelscope.cn/models/Tenc... 模型库。

下载完整模型库

css 复制代码
#命令行下载(下载至当前文件夹)
modelscope download --model Tencent-Hunyuan/Hunyuan-MT-7B --local_dir /Hunyuan-MT-7B

查看

三、web页面启动

采用显卡RTX4090,用如下的app.py文件运行模型。

app.py:

less 复制代码
# gradio_demo.py
import os
import sys
import time
import signal
import subprocess
import atexit
import psutil
import gradio as gr
from openai import OpenAI

# -------------------- 1. vLLM 配置 --------------------
MODEL_PATH = "/root/sj-data/LargeModel/Hunyuan-MT-7B"
VLLM_PORT  = 8021
VLLM_CMD = [    sys.executable, "-m", "vllm.entrypoints.openai.api_server",    "--host", "0.0.0.0",    "--port", str(VLLM_PORT),    "--trust-remote-code",    "--model", MODEL_PATH,    "--gpu_memory_utilization", "0.92",    "--tensor-parallel-size", "1",    "--dtype", "bfloat16",    "--disable-log-stats"]

# -------------------- 2. 进程管理 --------------------
vllm_proc = None

def cleanup():
    global vllm_proc
    if vllm_proc and vllm_proc.poll() is None:
        print("\n[INFO] 正在关闭 vLLM ...")
        for child in psutil.Process(vllm_proc.pid).children(recursive=True):
            child.terminate()
        vllm_proc.terminate()
        vllm_proc.wait(timeout=5)
        vllm_proc.kill()

atexit.register(cleanup)
signal.signal(signal.SIGINT,  lambda *_: cleanup())
signal.signal(signal.SIGTERM, lambda *_: cleanup())

def wait_port(port, timeout=120):
    import socket
    start = time.time()
    while True:
        try:
            with socket.create_connection(("localhost", port), timeout=1):
                print(f"[INFO] vLLM 端口 {port} 已就绪 ✔")
                return
        except Exception:
            if time.time() - start > timeout:
                raise RuntimeError("等待 vLLM 超时")
            time.sleep(1)

# -------------------- 3. 启动 vLLM --------------------
print("[INFO] 启动 vLLM ...")
vllm_proc = subprocess.Popen(VLLM_CMD, stdout=sys.stdout, stderr=sys.stderr)
wait_port(VLLM_PORT)

# -------------------- 4. Gradio 聊天 --------------------
client = OpenAI(api_key="EMPTY", base_url=f"http://localhost:{VLLM_PORT}/v1")

SYSTEM_PROMPT = "你是一个乐于助人的中文 AI 助手。"
STOP_TOKENS   = ["<|im_end|>"]

def chat_fn(message, history):
    msgs = [{"role": "system", "content": SYSTEM_PROMPT}]
    for h, a in history:
        msgs += [{"role": "user", "content": h}, {"role": "assistant", "content": a}]
    msgs.append({"role": "user", "content": message})

    stream = client.chat.completions.create(
        model=MODEL_PATH,
        messages=msgs,
        temperature=0.6,
        top_p=0.9,
        stream=True,
        extra_body={"top_k": 20, "repetition_penalty": 1.05, "stop": STOP_TOKENS}
    )
    partial = ""
    for ch in stream:
        partial += ch.choices[0].delta.content or ""
        yield partial

# 明亮配色方案的全屏CSS样式
custom_css = """
/* 全局样式 - 全屏设计 */
.gradio-container {
    max-width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    min-height: 100vh;
    height: 100vh;
    overflow: hidden;
}

/* 标题区域 */
.header {
    text-align: center;
    padding: 1rem 0;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    position: sticky;
    top: 0;
    z-index: 100;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}

.header-title {
    font-size: 1.8rem;
    font-weight: 700;
    margin-bottom: 0.25rem;
    letter-spacing: -0.02em;
    background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.header-subtitle {
    font-size: 1rem;
    opacity: 0.7;
    font-weight: 400;
    color: #64748b;
}

/* 主容器 */
.main-container {
    height: calc(100vh - 80px) !important;
    display: flex;
    flex-direction: column;
    padding: 0;
    margin: 0;
    background: transparent;
}

/* 聊天容器 - 全屏高度 */
.chat-container {
    background: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(12px);
    border-radius: 0;
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid rgba(0, 0, 0, 0.1);
    margin: 0;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}

/* 聊天历史区域 - 占据大部分空间 */
#chatbot {
    flex-grow: 1;
    padding: 1.5rem;
    overflow-y: auto;
    background: transparent;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    height: calc(100% - 120px) !important;
    scrollbar-width: thin;
    scrollbar-color: rgba(59, 130, 246, 0.5) transparent;
}

/* 自定义滚动条 */
#chatbot::-webkit-scrollbar {
    width: 6px;
}

#chatbot::-webkit-scrollbar-track {
    background: transparent;
}

#chatbot::-webkit-scrollbar-thumb {
    background-color: rgba(59, 130, 246, 0.5);
    border-radius: 3px;
}

#chatbot::-webkit-scrollbar-thumb:hover {
    background-color: rgba(59, 130, 246, 0.7);
}

/* 消息气泡样式 */
.message {
    max-width: 75%;
    padding: 1.25rem 1.5rem;
    border-radius: 20px;
    line-height: 1.6;
    animation: fadeInUp 0.4s ease forwards;
    position: relative;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
    backdrop-filter: blur(4px);
}

@keyframes fadeInUp {
    from { 
        opacity: 0; 
        transform: translateY(20px) scale(0.95);
    }
    to { 
        opacity: 1; 
        transform: translateY(0) scale(1);
    }
}

/* 用户消息 */
.message.user {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.9) 0%, rgba(99, 102, 241, 0.9) 100%);
    color: white;
    align-self: flex-end;
    border-bottom-right-radius: 6px;
    margin-left: auto;
}

/* AI消息 */
.message.bot {
    background: rgba(255, 255, 255, 0.9);
    color: #1e293b;
    align-self: flex-start;
    border-bottom-left-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

/* 消息时间戳 */
.message-time {
    font-size: 0.75rem;
    opacity: 0.6;
    margin-top: 0.5rem;
    display: block;
}

/* 输入区域 - 固定在底部 */
.input-container {
    padding: 1.5rem;
    background: rgba(255, 255, 255, 0.9);
    backdrop-filter: blur(12px);
    border-top: 1px solid rgba(0, 0, 0, 0.1);
    display: flex;
    gap: 1rem;
    align-items: center;
    width: 100%;
    margin: 0;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
}

/* 输入框样式 - 与对话框等宽 */
#user_input {
    flex-grow: 1;
    border-radius: 24px;
    padding: 1.25rem 1.5rem;
    border: 1px solid rgba(0, 0, 0, 0.1);
    font-size: 1rem;
    transition: all 0.3s ease;
    resize: none;
    background: rgba(255, 255, 255, 0.9);
    color: #1e293b;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
    min-height: 25px;
}

#user_input::placeholder {
    color: #94a3b8;
}

#user_input:focus {
    border-color: rgba(59, 130, 246, 0.8);
    outline: none;
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
    background: rgba(255, 255, 255, 1);
}

/* 按钮样式 */
#submit_btn {
    background: linear-gradient(135deg, #3b82f6 0%, #6366f1 100%);
    color: white;
    border-radius: 24px;
    padding: 1.25rem 2rem;
    font-weight: 600;
    transition: all 0.3s ease;
    border: none;
    min-width: 100px;
    box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
    position: relative;
    overflow: hidden;
}

#submit_btn::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
    transition: all 0.6s ease;
}

#submit_btn:hover::before {
    left: 100%;
}

#submit_btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(59, 130, 246, 0.4);
}

#clear_btn {
    background: rgba(255, 255, 255, 0.9);
    color: #64748b;
    border-radius: 24px;
    padding: 1.25rem 1.5rem;
    font-weight: 500;
    transition: all 0.3s ease;
    border: 1px solid rgba(0, 0, 0, 0.1);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}

#clear_btn:hover {
    background: rgba(255, 255, 255, 1);
    color: #334155;
    border-color: rgba(0, 0, 0, 0.2);
}

/* 响应式调整 */
@media (max-width: 768px) {
    .gradio-container {
        padding: 0;
    }
  
    .message {
        max-width: 85%;
        padding: 1rem 1.25rem;
    }
  
    .input-container {
        padding: 1rem;
        flex-direction: column;
    }
  
    #user_input {
        width: 100%;
    }
  
    #submit_btn, #clear_btn {
        width: 100%;
        text-align: center;
    }
}

/* 加载动画 */
.typing-animation {
    display: inline-flex;
    align-items: center;
}

.typing-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background-color: #3b82f6;
    margin: 0 3px;
    animation: typingAnimation 1.4s infinite ease-in-out;
}

.typing-dot:nth-child(1) { animation-delay: 0s; }
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
.typing-dot:nth-child(3) { animation-delay: 0.4s; }

@keyframes typingAnimation {
    0%, 60%, 100% {
        transform: translateY(0);
        opacity: 0.5;
    }
    30% {
        transform: translateY(-10px);
        opacity: 1;
    }
}

/* 消息状态指示器 */
.message-status {
    font-size: 0.75rem;
    opacity: 0.6;
    text-align: right;
    margin-top: 0.25rem;
}
"""

# 构建高级全屏界面
with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
    # 页面标题
    with gr.Column(elem_classes="header"):
        gr.Markdown("### Hunyuan-MT-7B 智能助手", elem_classes="header-title")
        gr.Markdown("全屏沉浸式对话体验", elem_classes="header-subtitle")
  
    # 主容器
    with gr.Column(elem_classes="main-container"):
        # 聊天容器
        with gr.Column(elem_classes="chat-container"):
            # 聊天记录 - 占据大部分空间
            chatbot = gr.Chatbot(
                label="聊天记录",
                bubble_full_width=False,
                show_label=False,
                avatar_images=(None, "https://picsum.photos/id/1005/200/200"),  # AI头像
                height="100%"
            )
        
            # 输入区域 - 固定在底部,与对话框等宽
            with gr.Row(elem_classes="input-container"):
                msg = gr.Textbox(
                    placeholder="请输入您的问题...",
                    elem_id="user_input",
                    container=False,
                    scale=8,
                    lines=1,
                    max_lines=5
                )
                with gr.Column(scale=1, min_width=120):
                    submit_btn = gr.Button("发送", elem_id="submit_btn")
                with gr.Column(scale=1, min_width=120):
                    clear_btn = gr.Button("清除历史", elem_id="clear_btn")
  
    # 提交消息处理函数
    def submit_message(message, history):
        if not message.strip():  # 忽略空消息
            return "", history
        # 添加用户消息到历史记录
        history.append((message, ""))
        yield "", history
    
        # 流式获取AI响应
        for response in chat_fn(message, history[:-1]):  # 排除刚添加的空回复
            history[-1] = (message, response)
            yield "", history
  
    # 绑定事件
    msg.submit(
        fn=submit_message,
        inputs=[msg, chatbot],
        outputs=[msg, chatbot]
    )
  
    submit_btn.click(
        fn=submit_message,
        inputs=[msg, chatbot],
        outputs=[msg, chatbot]
    )
  
    # 清除对话
    clear_btn.click(
        fn=lambda: None,
        inputs=None,
        outputs=chatbot,
        queue=False
    )

if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=8080, share=False)

四、页面展示

bash 复制代码
#激活环境
conda activate Hunyuan-MT
#进入项目
cd Hunyuan-MT/Hunyuan-MT
#执行基于gradio+vllm模型部署文件
python app.py

出现以下 Gradio 页面,即是模型已搭建完成。

相关推荐
机器之心2 小时前
LLM开源2.0大洗牌:60个出局,39个上桌,AI Coding疯魔,TensorFlow已死
人工智能·openai
FIT2CLOUD飞致云2 小时前
SQLBot开源智能问数系统成功进入GitHub趋势榜主榜,Star数突破2,000个!
开源
Juchecar3 小时前
交叉熵:深度学习中最常用的损失函数
人工智能
林木森ai3 小时前
爆款AI动物运动会视频,用Coze(扣子)一键搞定全流程(附保姆级拆解)
人工智能·aigc
聚客AI4 小时前
🙋‍♀️Transformer训练与推理全流程:从输入处理到输出生成
人工智能·算法·llm
BeerBear5 小时前
【保姆级教程-从0开始开发MCP服务器】一、MCP学习压根没有你想象得那么难!.md
人工智能·mcp
小气小憩6 小时前
“暗战”百度搜索页:Monica悬浮球被“围剿”,一场AI Agent与传统巨头的流量攻防战
前端·人工智能
神经星星6 小时前
准确度提升400%!印度季风预测模型基于36个气象站点,实现城区尺度精细预报
人工智能
IT_陈寒8 小时前
JavaScript 性能优化:5 个被低估的 V8 引擎技巧让你的代码快 200%
前端·人工智能·后端