一、模型介绍
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文件运行模型。
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 页面,即是模型已搭建完成。