环境准备
本次实战基于 AutoDL 服务器环境,具体配置如下:
- 操作系统:Ubuntu 22.04
- Python 版本:3.10
- PyTorch:2.1.0
- CUDA:12.1
- 显卡:RTX 4090 (24GB)
1. 搭建 LLaMA-Factory 环境
首先创建独立的虚拟环境并激活:
conda create -n llamafactory python=3.10 -y
conda activate llamafactory
将项目克隆至数据盘(例如 /root/autodl-tmp),并以可编辑模式安装依赖:
cd ./autodl-tmp/
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e .
数据集准备
将准备好的数据集文件拷贝至 data 目录下。假设数据集名为 llamafactory_style_data,需确保目录结构正确。
同时,在 data/data_info.json 中注册该数据集,使用相对路径即可:
"llamafactory_style_data": {
"file_name": "llamafactory_style_data.json"
}
2. 模型微调流程
下载基座模型
若无法直接访问 HuggingFace,可通过魔塔社区下载。本例选用 Qwen1.5-4B-Chat 作为基座模型。
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen1.5-4B-Chat', cache_dir="/root/autodl-tmp/models")
启动 Web UI 进行训练
进入项目目录启动 WebUI:
cd LLaMA-Factory
llamafactory-cli webui
在界面中配置以下关键参数,根据显存情况灵活调整:
- 模型名称:Qwen1.5-4B-Chat
- 模型路径:指向本地下载的模型目录
- 量化等级:8bit(可选,有助于节省显存)
- 训练轮次:300(建议设置稍大,可随时中断)
- 最大样本数:1000
- 截断长度:512(视文本长度而定)
- Batch Size:12(注意避免 OOM)
- 验证集比例:0.02
导出合并后的模型
训练完成后,需要合并 LoRA 权重。新建导出目录(如 /root/autodl-tmp/models_merge/qwen),设备选择 auto 以加速导出过程。
推理验证
在 WebUI 的推理模块中,加载训练好的权重路径(通常位于 saves/{model_name}/lora/train_{date}/checkpoint-{step})。推理后端建议选择 huggingface;若选择 vllm,需确保已安装兼容版本(如 vllm==0.11.0)且在同一环境中。
3. vLLM 部署与服务
安装 vLLM
pip install vllm==0.11.0
启动服务
vLLM 启动时会预分配 KV Cache 显存,若遇显存不足,最佳方案是调小最大序列长度:
# 默认端口为 8000
vllm serve /root/autodl-tmp/models_merge/qwen --max-model-len 32000
构建验证应用
为了直观测试效果,可以使用 Streamlit 编写一个简单的聊天前端。注意 model 参数必须指定合并后模型的绝对路径,否则可能报 404 错误。
import streamlit as st
from openai import OpenAI
st.set_page_config(page_title="VLLM Chat Demo", page_icon="🤖")
st.title("VLLM Chat Demo")
@st.cache_resource
def init_client():
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
return client
if "client" not in st.session_state:
st.session_state.client = init_client()
if "messages" not in st.session_state:
st.session_state.messages = [{"role": "assistant", "content": "你好,我是 AI 助手,有什么我可以帮助你的吗?"}]
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.write(message["content"])
def clear_chat_history():
st.session_state.messages = [{"role": "assistant", "content": "你好,我是 AI 助手,有什么我可以帮助你的吗?"}]
st.sidebar.button('清空聊天历史', on_click=clear_chat_history)
def generate_response(prompt_input):
try:
messages = st.session_state.messages.copy()
response = st.session_state.client.chat.completions.create(
model="/root/autodl-tmp/models_merge/qwen",
messages=messages,
temperature=0.7,
max_tokens=512,
stream=False
)
return response.choices[0].message.content
except Exception as e:
return f"请求出错:{str(e)}"
if prompt := st.chat_input("请输入您的问题:"):
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.write(prompt)
with st.chat_message("assistant"):
with st.spinner("正在思考..."):
response = generate_response(prompt)
st.write(response)
st.session_state.messages.append({"role": "assistant", "content": response})
st.sidebar.markdown("### 配置信息")
st.sidebar.info(f"模型:Qwen1.5-4B-Chat")
st.sidebar.info(f"API 端点:http://localhost:8000/v1")
运行应用:
streamlit run ./app.py
默认访问地址为 http://localhost:8501/。若微调效果未达预期,可适当增加训练轮次或优化数据集质量。


