gup服务器环境初始化

机器申请

在星海算力购买gpu服务器

image.png

创建实例

选择如下配置

  • CPU: 14核心
  • 内存: 60GB
  • GPU: RTX 4090D*1卡
  • CUDA版本: 11.8
  • 显存: 24GB
  • 镜像: Pytorch-22.04/Pytorch2.1.2/CUDA11.8
  • 系统盘: 26.24GB/100GB
  • 磁盘费用: 100GB(免费) 0GB(付费)

ssh连接到gpu服务器

image.png

初始化开发环境

image.png

安装git-lfs

sudo apt update
sudo apt install git-lfs
git lfs install

创建工作目录

pwd 
mkdri  projects
cd projects

下载模型文件

选择 Qwen2.5-0.5B-Instruct
终端执行命令:

git clone https://www.modelscope.cn/Qwen/Qwen2.5-0.5B-Instruct.git

完成下载,整个模型文件目录1.9G

(base) root@xb2-7769:~# du -h ./Qwen2.5-0.5B-Instruct/
80K     ./Qwen2.5-0.5B-Instruct/.git/hooks
8.0K    ./Qwen2.5-0.5B-Instruct/.git/logs/refs/remotes/origin
12K     ./Qwen2.5-0.5B-Instruct/.git/logs/refs/remotes
8.0K    ./Qwen2.5-0.5B-Instruct/.git/logs/refs/heads
24K     ./Qwen2.5-0.5B-Instruct/.git/logs/refs
32K     ./Qwen2.5-0.5B-Instruct/.git/logs
4.0K    ./Qwen2.5-0.5B-Instruct/.git/branches
8.0K    ./Qwen2.5-0.5B-Instruct/.git/refs/remotes/origin
12K     ./Qwen2.5-0.5B-Instruct/.git/refs/remotes
4.0K    ./Qwen2.5-0.5B-Instruct/.git/refs/tags
8.0K    ./Qwen2.5-0.5B-Instruct/.git/refs/heads
28K     ./Qwen2.5-0.5B-Instruct/.git/refs
4.0K    ./Qwen2.5-0.5B-Instruct/.git/lfs/tmp
4.0K    ./Qwen2.5-0.5B-Instruct/.git/lfs/incomplete
943M    ./Qwen2.5-0.5B-Instruct/.git/lfs/objects/fd/f7
943M    ./Qwen2.5-0.5B-Instruct/.git/lfs/objects/fd
943M    ./Qwen2.5-0.5B-Instruct/.git/lfs/objects
943M    ./Qwen2.5-0.5B-Instruct/.git/lfs
3.7M    ./Qwen2.5-0.5B-Instruct/.git/objects/pack
4.0K    ./Qwen2.5-0.5B-Instruct/.git/objects/info
3.7M    ./Qwen2.5-0.5B-Instruct/.git/objects
8.0K    ./Qwen2.5-0.5B-Instruct/.git/info
947M    ./Qwen2.5-0.5B-Instruct/.git
1.9G    ./Qwen2.5-0.5B-Instruct/

image.png

python3.10环境

本服务器默认python环境是3.8,版本比较老,刚好自带安装过 conda,所以决定使用conda创建python3.10环境

  • 创建py310env
conda create --name py310env python=3.10
  • 激活虚拟环境
conda activate py310env
  • 退出虚拟环境
conda deactivate

安装依赖

pip install transformers torch

跑通quickstart

# coding = utf-8
from transformers import AutoModelForCausalLM, AutoTokenizer

model_name = "Qwen2.5-0.5B-Instruct"

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

prompt = "Give me a short introduction to large language model."
messages = [
    {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

image.png
成功运行表示环境ok

项目说明

  • 主题:

    • 酒店评论情感识别
  • 背景:

    • 评论:来自携程酒店评论
    • 情感:分为正面和负面
  • 流程:

      1. 设计一个Prompt, 实现情感识别任务
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 模型名称
model_name = "Qwen2.5-0.5B-Instruct"

# 加载模型和分词器
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 定义提示词和评论
prompt_template = """
请阅读以下评论,并判断其情感倾向是正面还是负面。回答正面或者负面即可。

评论: "{}"
回答:
"""

# 读取 tsv文件 [("xxxxx","正面"),("xxxxx","反面")]
with open("情感识别.tsv", "r") as f:
    comments = [(line.strip().split("\t")[0], line.strip().split("\t")[1]) for line in f.readlines()[1:]]

def generate_response(prompt):
    # 构建消息
    messages = [
        {"role": "system", "content": "You are Qwen, created by Alibaba Cloud. You are a helpful assistant."},
        {"role": "user", "content": prompt}
    ]
    # 准备输入
    text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
    inputs = tokenizer([text], return_tensors="pt").to(model.device)

    # 生成响应
    outputs = model.generate(**inputs, max_new_tokens=512)
    response = tokenizer.batch_decode(outputs[:, inputs.input_ids.shape[-1]:], skip_special_tokens=True)[0]

    return response


if __name__ == '__main__':

# 处理每条评论
    for comment,answer in comments:
        prompt = prompt_template.format(comment)
        response = generate_response(prompt)
        print(f"评论: {comment}")
        print(f"判断: {response}  样本: {answer}")
        print("-" * 20)

    1. 借助LangChain,开发一个情感识别的Chain
    from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
   from langchain.prompts import PromptTemplate
   from langchain.chains import LLMChain
   from langchain_community.llms import HuggingFacePipeline
   import torch
   # 加载本地模型和分词器
   model_name = "Qwen2.5-0.5B-Instruct"
   model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16, device_map="auto")
   tokenizer = AutoTokenizer.from_pretrained(model_name)

   # 使用 transformers 的 pipeline 创建一个 HuggingFacePipeline
   # 设置参数以获得更稳定的输出
   pipe = pipeline(
       "text-generation",
       model=model,
       tokenizer=tokenizer,
       max_new_tokens=2,  # 限制生成长度
       temperature=0.1,    # 降低随机性
       top_p=0.9,         # 控制生成文本的多样性
       repetition_penalty=1.2  # 避免重复
   )

   # 创建一个 HuggingFacePipeline 对象
   llm = HuggingFacePipeline(pipeline=pipe)

   # 优化后的提示模板
   prompt_template = PromptTemplate(
       input_variables=["text"],
       template="""你是一个专业的情感分析专家。请仔细分析以下评论的情感倾向。回答"正面"或者"负面"即可,不要其他内容

   评论内容:"{text}"

   最终判断为:"""
   )

   # 创建一个 LLMChain
   chain = LLMChain(
       llm=llm,
       prompt=prompt_template
   )

    1. 调用这个Chain,在情感识别数据集上,测试准确率
  # 测试用例
  # 读取 tsv文件 [("xxxxx","正面"),("xxxxx","反面")]
  with open("情感识别.tsv", "r") as f:
      test_cases = [(line.strip().split("\t")[0], line.strip().split("\t")[1]) for line in f.readlines()[1:]]

  # 处理结果的函数
  def process_result(result):
      res = result.split("\n")[-1]
      # 使用正则表达式提取"正面"或"负面"
      match = re.search(r"(正面|负面)", res)
      if match:
          return match.group(0)
      return "无法判断"

  # 测试多个案例
  for test_text,answer in test_cases:
      print("\n评论:", test_text)
      result = chain.run({"text": test_text})
      final_result = process_result(result)
      print(f"判断的情感倾向: {final_result}, 真实的情感倾向: {answer}")
    1. 不断调整 Prompt, 逐步提升准确率
# 优化后的提示模板
  prompt_template = PromptTemplate(
      input_variables=["text"],
      template="""你是一个专业的情感分析专家。请仔细分析以下评论的情感倾向。回答"正面"或者"负面"即可,不要其他内容

  评论内容:"{text}"

  最终判断为:"""
)
    1. 把最终开发好的Chain,发布成大模型能力 API
# -*- coding: utf-8 -*-
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain_community.llms import HuggingFacePipeline
import torch
import uvicorn

# 创建 FastAPI 应用
app = FastAPI(
    title="情感分析 API",
    description="基于 Qwen 大模型的情感分析服务",
    version="1.0.0"
)

# 定义请求模型
class SentimentRequest(BaseModel):
    text: str

# 定义响应模型
class SentimentResponse(BaseModel):
    text: str
    sentiment: str

# 全局变量存储模型和链
global_chain = None

# 初始化模型和链
def init_model():
    global global_chain

    # 加载模型和分词器
    model_name = "Qwen2.5-0.5B-Instruct"
    model = AutoModelForCausalLM.from_pretrained(
        model_name,
        torch_dtype=torch.float16,
        device_map="auto"
    )
    tokenizer = AutoTokenizer.from_pretrained(model_name)

    pipe = pipeline(
        "text-generation",
        model=model,
        tokenizer=tokenizer,
        max_new_tokens=2,  # 限制生成长度
        temperature=0.1,  # 降低随机性
        top_p=0.9,  # 控制生成文本的多样性
        repetition_penalty=1.2  # 避免重复
    )

    # 创建一个 HuggingFacePipeline 对象
    llm = HuggingFacePipeline(pipeline=pipe)

    # 优化后的提示模板
    prompt_template = PromptTemplate(
        input_variables=["text"],
        template="""你是一个专业的情感分析专家。请仔细分析以下评论的情感倾向。回答"正面"或者"负面"即可,不要其他内容
        评论内容:"{text}"
        断定为:
     
     """
    )

    # 创建链
    global_chain = LLMChain(
        llm=llm,
        prompt=prompt_template
    )

# 启动时初始化模型
@app.on_event("startup")
async def startup_event():
    init_model()

# 健康检查端点
@app.get("/health")
async def health_check():
    return {"status": "healthy"}

# 情感分析端点
@app.post("/analyze_sentiment", response_model=SentimentResponse)
async def analyze_sentiment(request: SentimentRequest):
    try:
        # 使用链进行分析
        result = global_chain.run({"text": request.text})
        sentiment = result.split("\n")[-1]

        return SentimentResponse(
            text=request.text,
            sentiment=sentiment
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

# 主函数
if __name__ == "__main__":
    # 运行服务器
    uvicorn.run(app, host="0.0.0.0", port=8000)

健康检测

(py310env) root@xb2-7769:~# curl --request GET \
>   --url http://0.0.0.0:8000/health \
>   --header 'Accept: */*' \
>   --header 'Accept-Encoding: gzip, deflate, br' \
>   --header 'Connection: keep-alive' \
>   --header 'User-Agent: PostmanRuntime-ApipostRuntime/1.1.0'
{"status":"healthy"}

接口测试

image.png

posted @ 2025-01-09 11:20  春水鸿鹄  阅读(1)  评论(0编辑  收藏  举报