跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Llama 3.1 本地部署与 API 服务搭建

综述由AI生成Llama 3.1-8B 模型的本地部署流程,涵盖 Conda 环境搭建、PyTorch 与 Transformers 库安装、模型加载测试以及基于 FastAPI 构建长期运行的 API 服务。此外,文章还讲解了如何通过 SSH 隧道实现跨服务器调用,并提供了针对端口占用、连接不稳定等常见问题的排查与解决步骤。

未来可期发布于 2026/4/6更新于 2026/5/2330 浏览

Llama 3.1 本地部署与 API 服务搭建

一、环境准备

部署服务器: H100 80G 模型: Llama-3.1-8B-Instruct

1. 创建 Conda 虚拟环境

建议使用 Python 3.10 以上版本。

conda create -n llama3 python=3.11

2. 激活环境

conda activate llama3

3. 安装 PyTorch

查看 CUDA 版本:

nvidia-smi

根据 CUDA 版本选择适合的 PyTorch 版本(建议选择不大于主机支持的最高版本),使用镜像源安装:

pip install torch==2.6.0 torchvision==0.21.0 torchaudio==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

4. 升级 Pip 及工具

python -m pip install --upgrade pip
wget --version
md5sum --version

若缺少 wget 或 md5sum,可执行:

apt-get install wget
apt-get install md5sum

5. 安装依赖库

pip install --upgrade transformers
pip install accelerate -i https://pypi.tuna.tsinghua.edu.cn/simple

二、本地部署模型测试

从 HuggingFace 下载模型:https://huggingface.co/meta-llama/Llama-3.1-8B

代码示例

import transformers
import torch

model_id = "meta-llama/Meta-Llama-3.1-8B-Instruct"
pipeline = transformers.pipeline(
    "text-generation",
    model=model_id,
    model_kwargs={"torch_dtype": torch.bfloat16},
    device_map="auto"
)

messages = [
    {"role": "system", "content": "You are a pirate chatbot who always responds in pirate speak!"},
    {"role": "user", "content": }
]

outputs = pipeline(messages, max_new_tokens=)
(outputs[][][-])
"Who are you?"
256
print
0
"generated_text"
1

三、本地部署长期运行的 API 服务

1. 安装所需包

pip install fastapi uvicorn pydantic -i https://pypi.tuna.tsinghua.edu.cn/simple

2. 创建 API 服务文件 (api_server.py)

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import uvicorn
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

MODEL_PATH = "<MODEL_PATH>"

class ChatMessage(BaseModel):
    role: str
    content: str

class ChatRequest(BaseModel):
    messages: List[ChatMessage]
    max_tokens: Optional[int] = 200
    temperature: Optional[float] = 0.7
    top_p: Optional[float] = 0.9

class ChatResponse(BaseModel):
    response: str
    usage: dict

app = FastAPI(title="Llama 3.1 API", version="1.0")
model = None
tokenizer = None
pipe = None

@app.on_event("startup")
async def startup_event():
    global model, tokenizer, pipe
    logger.info("正在加载模型...")
    try:
        tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
        model = AutoModelForCausalLM.from_pretrained(
            MODEL_PATH,
            torch_dtype=torch.float16,
            device_map="auto",
            low_cpu_mem_usage=True
        )
        pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, device=0 if torch.cuda.is_available() else -1)
        logger.info(f"模型加载完成!设备:{model.device}")
    except Exception as e:
        logger.error(f"模型加载失败:{e}")
        raise

@app.get("/")
async def root():
    return {"service": "Llama 3.1 API", "status": "running", "model": "Llama-3.1-8B-Instruct", "device": str(model.device) if model else "未加载"}

@app.get("/health")
async def health_check():
    return {"status": "healthy"}

@app.post("/chat/completions", response_model=ChatResponse)
async def chat_completions(request: ChatRequest):
    try:
        text = tokenizer.apply_chat_template([msg.dict() for msg in request.messages], tokenize=False, add_generation_prompt=True)
        outputs = pipe(text, max_new_tokens=request.max_tokens, temperature=request.temperature, top_p=request.top_p, do_sample=True, pad_token_id=tokenizer.eos_token_id)
        response_text = outputs[0]['generated_text']
        if "assistant" in response_text:
            response_text = response_text.split("assistant")[-1].strip()
        else:
            response_text = response_text.replace(text, "").strip()
        input_tokens = len(tokenizer.encode(text))
        output_tokens = len(tokenizer.encode(response_text))
        return ChatResponse(
            response=response_text,
            usage={"prompt_tokens": input_tokens, "completion_tokens": output_tokens, "total_tokens": input_tokens + output_tokens}
        )
    except Exception as e:
        logger.error(f"生成失败:{e}")
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000, log_level="info")

3. 启动 API 服务

前台运行:

python api_server.py

4. 测试 API

curl http://localhost:8000/
curl http://localhost:8000/health
curl -X POST "http://localhost:8000/chat/completions" \
-H "Content-Type: application/json" \
-d '{ "messages": [ {"role": "system", "content": "你是一个有用的 AI 助手"}, {"role": "user", "content": "中国的首都是哪里?" } ], "max_tokens": 100 }'

四、跨服务器部署与使用的 API 服务

1. 服务器端 (H100)

部署脚本 (h100_server.py)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
import uvicorn
import logging
import time
import os
from contextlib import asynccontextmanager

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

MODEL_PATH = "<MODEL_PATH>"
model = None
tokenizer = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global model, tokenizer
    logger.info("正在 H100 上加载 Llama-3.1-8B-Instruct 模型...")
    try:
        tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH)
        if tokenizer.pad_token is None:
            tokenizer.pad_token = tokenizer.eos_token
        model = AutoModelForCausalLM.from_pretrained(
            MODEL_PATH,
            torch_dtype=torch.float16,
            device_map="auto",
            low_cpu_mem_usage=True
        )
        logger.info(f"✅ 模型加载成功!设备:{model.device}")
        yield
    except Exception as e:
        logger.error(f"❌ 模型加载失败:{e}")
        raise RuntimeError("模型初始化失败") from e
    finally:
        if model is not None:
            del model
            torch.cuda.empty_cache()

app = FastAPI(
    title="Llama 3.1 Instruct API",
    description="OpenAI-compatible API for Llama-3.1-8B-Instruct on H100",
    version="1.0",
    lifespan=lifespan
)

class ChatMessage(BaseModel):
    role: str
    content: str

class ChatCompletionRequest(BaseModel):
    model_config = ConfigDict(extra="ignore")
    messages: Optional[List[ChatMessage]] = None
    prompt: Optional[str] = None
    model: str = "llama-3.1-8b"
    max_tokens: int = 200
    temperature: float = 0.7
    top_p: float = 0.9
    stream: bool = False

@app.get("/")
async def root():
    return {"service": "Llama 3.1 Instruct API", "status": "running", "device": str(model.device) if model else "uninitialized"}

@app.get("/health")
async def health_check():
    return {"status": "healthy", "model_loaded": model is not None}

@app.post("/v1/chat/completions")
async def chat_completions(request: ChatCompletionRequest):
    if model is None or tokenizer is None:
        raise HTTPException(status_code=503, detail="模型尚未加载完成")
    if request.stream:
        raise HTTPException(status_code=400, detail="流式输出暂不支持")
    try:
        if request.messages is None:
            raise ValueError("messages 不能为空")
        messages_dict = [msg.model_dump() for msg in request.messages]
        encoding = tokenizer.apply_chat_template(messages_dict, add_generation_prompt=True, return_tensors="pt")
        input_ids = encoding.input_ids.to(model.device)
        input_length = input_ids.shape[1]
        start_time = time.time()
        with torch.no_grad():
            outputs = model.generate(input_ids=input_ids, max_new_tokens=request.max_tokens, temperature=request.temperature, top_p=request.top_p, do_sample=True, pad_token_id=tokenizer.pad_token_id, eos_token_id=tokenizer.eos_token_id, use_cache=True)
        gen_time = time.time() - start_time
        new_tokens = outputs[0][input_length:]
        response_text = tokenizer.decode(new_tokens, skip_special_tokens=True).strip()
        return {
            "id": f"cmpl-{int(time.time())}",
            "created": int(time.time()),
            "model": request.model,
            "choices": [{"index": 0, "message": {"role": "assistant", "content": response_text}, "finish_reason": "stop"}],
            "usage": {"prompt_tokens": input_length, "completion_tokens": len(new_tokens), "total_tokens": input_length + len(new_tokens)}
        }
    except Exception as e:
        logger.error(f"❌ 生成错误:{e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    port = int(os.getenv("PORT", 8000))
    uvicorn.run(app, host="0.0.0.0", port=port, log_level="info", workers=1)
启动服务
python h100_server.py

2. 客户端

建立 SSH 隧道

在本地终端执行(将 <REMOTE_IP> 替换为服务器 IP):

ssh -L 8000:localhost:8000 root@<REMOTE_IP> -p <SSH_PORT>

检查端口是否监听:

netstat -tuln | grep 8000
运行调用脚本 (client_llama3.py)
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8000/v1",
    api_key="not-needed"
)

response = client.chat.completions.create(
    model="llama-3.1-8b",
    messages=[
        {"role": "system", "content": "你是一个 helpful AI 助手。"},
        {"role": "user", "content": "你好,请介绍一下你自己。"}
    ],
    max_tokens=150
)
print(response.choices[0].message.content)

五、常见问题排查

1. 服务器端口被占用或无法连接

  • 更换端口:修改 uvicorn.run 中的 port 参数。
  • 停止进程:查找并杀掉占用端口的进程。
netstat -tulpn | grep :8000
kill -9 <PID>
  • 优化 SSH 连接:使用 -4 -N -L 参数建立隧道。
ssh -4 -N -L 8000:localhost:8000 root@<REMOTE_IP> -p <SSH_PORT>

2. SSH 连接不稳定

可编写脚本实现断线重连,设置环境变量后运行:

export SSH_TUNNEL_PASSWORD="your_password"
./ssh_tunnel.sh

脚本逻辑应包含自动检测端口状态、重启 SSH 隧道等功能,确保 ServerAliveInterval 等参数配置合理以维持长连接。

目录

  1. Llama 3.1 本地部署与 API 服务搭建
  2. 一、环境准备
  3. 1. 创建 Conda 虚拟环境
  4. 2. 激活环境
  5. 3. 安装 PyTorch
  6. 4. 升级 Pip 及工具
  7. 5. 安装依赖库
  8. 二、本地部署模型测试
  9. 代码示例
  10. 三、本地部署长期运行的 API 服务
  11. 1. 安装所需包
  12. 2. 创建 API 服务文件 (api_server.py)
  13. 3. 启动 API 服务
  14. 4. 测试 API
  15. 四、跨服务器部署与使用的 API 服务
  16. 1. 服务器端 (H100)
  17. 部署脚本 (h100_server.py)
  18. 启动服务
  19. 2. 客户端
  20. 建立 SSH 隧道
  21. 运行调用脚本 (client_llama3.py)
  22. 五、常见问题排查
  23. 1. 服务器端口被占用或无法连接
  24. 2. SSH 连接不稳定
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • RTK免像控验证:大疆RTK无人机免像控飞行与有像控成果精度对比
  • Java 主流 JDK 版本核心区别与流行原因分析
  • Dubbo 服务降级 Mock 机制详解与实战
  • Python 基础:容器公共操作与推导式详解
  • Spring Boot 与 Leaflet 构建省级旅游口号 WebGIS 可视化平台
  • 基于 n8n 与 API 的自动化资讯采集与摘要推送系统
  • ESP32-S3 本地 AI 模型推理能力与实战指南
  • VS Code 提示无 Python 环境,安装 uv 后的终端输出解读与解决
  • AI 商业价值与盈利趋势深度解析
  • 人工智能基础概念全解析:从图灵测试到深度学习
  • 谷歌 Bard 更新:支持内网搜索及日程安排
  • 知网 AIGC 检测未通过?3 种方法降低 AI 生成率至 15% 以下
  • 使用昇腾 Atlas 300I Duo 推理卡部署 32B 大语言模型 (MindIE+WebUI)
  • windows部署的OpenClaw接入飞书机器人
  • 延迟退休背景下 AI 工具在职业规划与健康管理中的应用
  • Docker 部署 MySQL 8.0 命令详解与参数说明
  • llama.cpp 部署 Qwen3-14B-Claude-4.5-Opus-High-Reasoning-Distill 模型
  • 前端实战:如何让用户回到上次阅读的位置?
  • 深入 llama.cpp:llama-server 从命令行到 HTTP Server
  • MC 骑士一百天整合包安装与配置指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online