基于FastAPI实现本地大模型API封装调用

  • 关于FastAPI
    • FastAPI 是一个现代、快速(高性能)的 Python Web 框架,用于构建基于标准 Python 类型提示的 API。它以简洁、直观和高效的方式提供工具,特别适合开发现代 web 服务和后端应用程序。
  • 问题:_pad() got an unexpected keyword argument ‘padding_side’
    • 解决:降级 transformers,pip install transformers==4.34.0,同时更改相关包版本以实现适配,pip install accelerate==0.25.0,pip install huggingface_hub==0.16.4
  • 问题:报错500
    • 服务器防火墙问题,只能在指定端口访问
    • post请求的参数通过request body传递,需要以 application/json 的方式 ,请求body
      • 以postman测试为例:Body中选择“raw”,则对应的Headers中的“Content-Type”“application/json”,参数形式是{"content":"有什么推荐的咖啡吗"}
        在这里插入图片描述
  • 代码实现
    • fastapi_demo.py(运行开启服务)
    • post.py(服务测试)
# fastapi_demo.py(运行开启服务)
from fastapi import FastAPI, Request, HTTPException
from transformers import AutoTokenizer, AutoModelForCausalLM, GenerationConfig
import uvicorn
import json
import datetime
import torch
import loggingprint(f"CUDA 是否可用: {torch.cuda.is_available()}")
print(f"当前 CUDA 版本: {torch.version.cuda}")
print(f"当前可用 CUDA 设备数量: {torch.cuda.device_count()}")# 设置设备参数
DEVICE = "cuda"  # 使用CUDA
DEVICE_ID = "0"  # CUDA设备ID,如果未设置则为空
CUDA_DEVICE = f"{DEVICE}:{DEVICE_ID}" if DEVICE_ID else DEVICE  # 组合CUDA设备信息# 清理GPU内存函数
def torch_gc():if torch.cuda.is_available():  # 检查是否可用CUDAwith torch.cuda.device(CUDA_DEVICE):  # 指定CUDA设备torch.cuda.empty_cache()  # 清空CUDA缓存torch.cuda.ipc_collect()  # 收集CUDA内存碎片# 构建 chat 模版
def bulid_input(prompt, history=[], system_message=None):system_format = 'system\n\n{content}\n'user_format = 'user\n\n{content}\n'assistant_format = 'assistant\n\n{content}\n'prompt_str = ''# 添加system消息if system_message:prompt_str += system_format.format(content=system_message)# 拼接历史对话for item in history:if item['role'] == 'user':prompt_str += user_format.format(content=item['content'])else:prompt_str += assistant_format.format(content=item['content'])# 添加当前用户输入prompt_str += user_format.format(content=prompt)return prompt_str# 创建FastAPI应用
app = FastAPI()# 添加GET请求处理
@app.get("/")
async def read_root():return {"message": "Welcome to the API. Please use POST method to interact with the model."}@app.get('/favicon.ico')
async def favicon():return {'status': 'ok'}# 处理POST请求的端点
@app.post("/")
async def create_item(request: Request):try:json_post_raw = await request.json()json_post = json.dumps(json_post_raw)json_post_list = json.loads(json_post)prompt = json_post_list.get('prompt')if not prompt:raise HTTPException(status_code=400, detail="提示词不能为空")history = json_post_list.get('history', [])system_message = json_post_list.get('system_message')# 添加输入验证的日志logging.info(f"收到请求: prompt={prompt}, history={history}, system_message={system_message}")input_str = bulid_input(prompt=prompt, history=history, system_message=system_message)try:input_ids = process_input(input_str).to(CUDA_DEVICE)except Exception as e:logging.error(f"Tokenizer 错误: {str(e)}")raise HTTPException(status_code=500, detail=f"Tokenizer 处理失败: {str(e)}")try:generated_ids = model.generate(input_ids=input_ids, max_new_tokens=1024, do_sample=True,top_p=0.5, temperature=0.95, repetition_penalty=1.1)except Exception as e:logging.error(f"模型生成错误: {str(e)}")raise HTTPException(status_code=500, detail=f"模型生成失败: {str(e)}")outputs = generated_ids.tolist()[0][len(input_ids[0]):]response = tokenizer.decode(outputs)response = response.strip().replace('assistant\n\n', '').strip()  # 解析 chat 模版now = datetime.datetime.now()  # 获取当前时间time = now.strftime("%Y-%m-%d %H:%M:%S")  # 格式化时间为字符串# 构建响应JSONanswer = {"response": response,"status": 200,"time": time}# 构建日志信息log = "[" + time + "] " + '", prompt:"' + prompt + '", response:"' + repr(response) + '"'print(log)  # 打印日志torch_gc()  # 执行GPU内存清理return answer  # 返回响应except json.JSONDecodeError:raise HTTPException(status_code=400, detail="无效的 JSON 格式")except Exception as e:logging.error(f"处理请求时发生错误: {str(e)}")raise HTTPException(status_code=500, detail=str(e))# 主函数入口
if __name__ == '__main__':# 首先检查可用的GPU数量gpu_count = torch.cuda.device_count()if int(DEVICE_ID) >= gpu_count:raise ValueError(f"指定的DEVICE_ID ({DEVICE_ID}) 无效。系统只有 {gpu_count} 个GPU设备(0-{gpu_count-1})")# 设置当前CUDA设备torch.cuda.set_device(int(DEVICE_ID))model_name_or_path = '/data/user23262833/MemoryStrategy/ChatGLM-Finetuning/chatglm3-6b(需要填写你的模型位置所在路径)'# 修改 tokenizer 初始化tokenizer = AutoTokenizer.from_pretrained(model_name_or_path,use_fast=False,trust_remote_code=True,padding_side='left'  # 直接在初始化时设置)# 更简单的 process_input 实现def process_input(text):inputs = tokenizer.encode(text, return_tensors='pt')return inputs if torch.is_tensor(inputs) else torch.tensor([inputs])model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map={"": int(DEVICE_ID)},  # 明确指定设备映射torch_dtype=torch.float16)# 启动FastAPI应用# 用6006端口可以将autodl的端口映射到本地,从而在本地使用apiuvicorn.run(app, host='需填写你的本地或者服务器ip', port=6006, workers=1)  # 在指定端口和主机上启动应用
# post.py
import requests
import jsondef get_completion(prompt):try:headers = {'Content-Type': 'application/json'}data = {"prompt": prompt}response = requests.post(url='需填写你的本地或者服务器ip:6006', headers=headers, data=json.dumps(data))# 检查响应状态码response.raise_for_status()# 添加响应内容的打印,用于调试print("Response content:", response.text)return response.json()['response']except requests.exceptions.RequestException as e:print(f"请求错误: {e}")return Noneexcept json.JSONDecodeError as e:print(f"JSON解析错误: {e}")return Noneexcept KeyError as e:print(f"响应中缺少 'response' 键: {e}")return None# 测试代码
response = get_completion('你好')
if response is not None:print(response)
  • 测试结果
    在这里插入图片描述
  • 参考博文:https://blog.csdn.net/qq_34717531/article/details/142092636?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7EPaidSort-1-142092636-blog-139909949.235%5Ev43%5Epc_blog_bottom_relevance_base5&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EOPENSEARCH%7EPaidSort-1-142092636-blog-139909949.235%5Ev43%5Epc_blog_bottom_relevance_base5&utm_relevant_index=1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19034.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

数字化点亮库布其沙漠的绿色梦想

Bentley 应用程序助力提升设计和施工效率,提前六周交付设计成果 清洁能源为沙漠带来新活力 库布其光伏治沙项目(以下简称“该项目”)位于内蒙古鄂尔多斯市库布其沙漠,占地约 10 万亩,是中国单体规模最大的光伏治沙项目…

基于单片机的风能太阳能供电的路灯智能控制系统设计(论文+源码)

1系统总体设计 本课题为风能太阳能供电的路灯智能控制系统设计,系统的主要功能设计如下: (1) 供电模块:采用太阳能板以及风机模拟风扇充电,经过充电电路给锂电池进行充电。再由锂电池给照明模块以及整个项…

Linux Centos7 Rocky网卡配置

目录 1.Vmare 虚拟机配置 (1)打开虚拟机输入ip a,查看ip网段,若为192.168.81.135 (2)在Vmare上的虚拟网络配置器配置 (3)确保电脑有VMnet1 VMnet8 2.Linux虚拟机Centos配置 &#…

MySQL索引原理之查询优化

MySQL索引原理之查询优化 1、慢查询定位 开启慢查询日志 查看 MySQL 数据库是否开启了慢查询日志和慢查询日志文件的存储位置的命令如下: SHOW VARIABLES LIKE %slow_query_log%通过如下命令开启慢查询日志: SET global slow_query_log 1; SET global …

ArchGuard 架构分析器发布:多语言、跨项目架构数据生成,助力 AI 时代知识挖掘...

TL;DR:https://github.com/archguard/archguard 过去的几个月里,我们一直在探索用 AI 辅助跨项目、跨大量微服务的系统的开发。其中一个重要的话题就是,从现有的软件架构去生成知识,文档是落后、多版本的, 只有代码才保…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息: 简介: 本文的背景是机器翻译(MT)任务的评估。在机器翻译领域,由于不同场景和语言对的需求差异&a…

工程车识别算法平台LiteAIServer算法定制工程车类型检测算法:建筑工地安全管理的得力助手

随着科技的飞速发展,智能化技术正在逐步改变我们的生活方式,特别是在交通管理和安全管理领域。其中,算法定制LiteAIServer工程车类型检测算法以其高效、准确和实时的特性,成为了建筑工地管理、矿山开采以及物流运输等多个领域的重…

机器学习2

三、特征工程 接机器学习1 4、特征降维 4.2、主成分分析PCA 从原始特征空间中找到一个新的坐标系统,使得数据在新坐标轴上的投影能够最大程度地保留数据的方差,同时减少数据的维度。 保留信息/丢失信息信息保留的比例 from sklearn.decomposition imp…

【Linux之权限】提升篇

前言 在前两篇文章里,我们已经学习了Linux中权限的理论、实践和重点,接下来我们将进一步提升对Linux权限的全面认知。虽是拓展,其实还是重点。 本文内容并不多,那我们就开始吧。 目录的权限该如何理解呢? 如果我想进…

亮数据结合AI大模型,实现数据自由

目录 一、获取网络数据的挑战1、反爬虫机制的威胁2、IP封锁与访问频率控制3、数据隐私与法律合规 二、亮数据动态代理:数据采集的最佳拍档1、高质量IP资源2、智能调度与自动切换3、合规与隐私保护4、多场景应用支持 三、使用亮数据代理 IP进行网络数据抓取1、引入 r…

elasticsearch是如何实现master选举的?

大家好,我是锋哥。今天分享关于【elasticsearch是如何实现master选举的?】面试题。希望对大家有帮助; elasticsearch是如何实现master选举的? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Elasticsearch 中&…

EtherNet/IP转Profinet网关连接发那科机器人配置实例解析

本案例主要展示了如何通过Ethernet/IP转Profinet网关实现西门子1200PLC与发那科搬运机器人的连接。所需的设备有西门子1200PLC、开疆智能Ethernet/IP转Profinet网关以及Fanuc机器人。 具体配置步骤:打开西门子博图配置软件,添加PLC。这是配置的第一步&am…

Uniapp运行环境判断和解决跨端兼容性详解

Uniapp运行环境判断和解决跨端兼容性 开发环境和生产环境 uniapp可通过process.env.NODE_ENV判断当前环境是开发环境还是生产环境,一般用于链接测试服务器或者生产服务器的动态切换。在HX中,点击运行编译出来的代码是开发环境,点击发行编译…

C语言 for 循环:解谜数学,玩转生活!

放在最前面的 🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼 🎉🎉我的C语言初阶合集:C语言初阶合集,希望能…

【专题】2024AIGC创新应用洞察报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p38310 在科技日新月异的今天,人工智能领域正以前所未有的速度发展,AIGC(人工智能生成内容)成为其中最耀眼的明珠。从其应用场景的不断拓展,到对各行业的深刻变革&#xff0…

.NET桌面应用架构Demo与实战|WPF+MVVM+EFCore+IOC+DI+Code First+AutoMapper

目录 .NET桌面应用架构Demo与实战|WPFMVVMEFCoreIOCDICode FirstAutoPapper技术栈简述项目地址:功能展示项目结构项目引用1. 新建模型2. Data层,依赖EF Core,实现数据库增删改查3. Bussiness层,实现具体的业务逻辑4. Service层&am…

两种柑橘物种中WRKY转录因子的鉴定和比较-文献精读82

Genome-wide identification and comparative expression profiling of the WRKY transcription factor family in two Citrus species with different Candidatus Liberibacter asiaticus susceptibility 全基因组范围内鉴定和比较两种对柑橘黄龙病菌(Candidatus …

Kafka中ACKS LSO LEO LW HW AR ISR OSR解析

名称解释 ACKS(Acknowledgments)确认、回执 LW(Low watermark)低水位、LSO(Log start offset)起始偏移量 HW(High watermark)高水位 LEO(Log end offset)…

vue实现展示并下载后端返回的图片流

// 点击下载 downLoadCode() {const image new Image();image.setAttribute("crossOrigin", "anonymous");image.onload () > {const canvas document.createElement("canvas");canvas.width image.width;canvas.height image.height;c…

c++:模板

1.泛型编程 在认识模板之前,我们首先要认识泛型编程 泛型编程是一种编程范式,它使得算法和数据结构能够独立于特定数据类型进行设计和实现。通过使用泛型,开发者可以编写一次代码,然后在不同的数据类型上进行重用,从…