首页 > 其他分享 >一个中转代码,底层调用openai,上层模拟openai

一个中转代码,底层调用openai,上层模拟openai

时间:2024-06-18 11:45:16浏览次数:10  
标签:stream 中转 resp messages content openai import model 底层

openai的调用api几乎成为了实质性的大模型社区的调用标准,你看不论是阿里的灵积,智谱,together,vllm,ollama,fastchat等都支持openai的调用方式,所以这也是大势所趋,

有时候我们想做个中间层,底层调用大模型,上层提供业务服务,特别是许多公司的多节点的agent,如果我们都保持一致那么统一性就很好了

代码如下,代码不是很精细,个别小细节需要改下,但是整体不影响使用和借鉴:

import time
import json
import asyncio
from typing import List, Optional

import uvicorn
from openai import OpenAI
from fastapi import FastAPI
from pydantic import BaseModel
from starlette.responses import StreamingResponse


app = FastAPI(title="OpenAI-compatible API")

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

class ChatCompletionRequest(BaseModel):
    model: str = "mock-gpt-model"
    messages: List[ChatMessage]
    max_tokens: Optional[int] = 512
    temperature: Optional[float] = 0.1
    stream: Optional[bool] = False




class CallOpenAI:
  '''调用底层大模型的部分 '''
  def __init__(self):
    self.client = OpenAI(
             api_key="EMPTY",
             base_url="http://127.0.0.1:9001/v1"
         )

  def invoke(self,messages):

     messages=[{'role':'user','content':messages}]

     completion = self.client.chat.completions.create(
          model='Qwen2-72-gptq-int4',
          messages=messages,
#          temperature = 0.5,
          max_tokens=500,
#          top_p=1.0,
#          presence_penalty=0.0,
#          frequency_penalty = 0.0
          stream=True

      )

     return completion
model = CallOpenAI()


async def _resp_async_generator1(text_resp: str):

   response = model.invoke(text_resp)
   stream_messages = ''

   for chunk in response:
     content = chunk.choices[0].delta.content
     stream_message = content
     if not content:
       stream_message = ''
     stream_messages += stream_message

     chunk = {
          "id": 1,
          "object": "chat.completion.chunk",
          "created": time.time(),
          "model": "blah",
          "choices": [{"delta": {"content": stream_message}}],
      }

     yield f"data: {json.dumps(chunk)}\n\n"
     await asyncio.sleep(0)
   yield "data: [DONE]\n\n"



@app.post("/v1/chat/completions")
async def chat_completions(request: ChatCompletionRequest):

    if request.messages:
      resp_content = "As a mock AI Assitant, I can only echo your last message:" + request.messages[-1].content
    else:
      resp_content = "As a mock AI Assitant, I can only echo your last message, but there wasn't one!"
    resp_content = '请基于春天写一篇1000字的文章'

    if request.stream:
      return StreamingResponse(_resp_async_generator1(resp_content), media_type="application/x-ndjson")

    return {
        "id": "1337",
        "object": "chat.completion",
        "created": time.time(),
        "model": request.model,
        "choices": [{
            "message": ChatMessage(role="assistant", content=resp_content)        }]
    }


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

拉起如下

写个代码测试下:

from openai import OpenAI

# init client and connect to localhost server
client = OpenAI(
    api_key="fake-api-key",
    base_url="http://localhost:8000/v1/" # change the default port if needed
)

stream = client.chat.completions.create(
    model="mock-gpt-model",
    messages=[{"role": "user", "content": "Say this is a test"}],
    stream=True,
)

for chunk in stream:
    print(chunk.choices[0].delta.content or "",end='',flush=True)

结果如下图进行流式输出

标签:stream,中转,resp,messages,content,openai,import,model,底层
From: https://www.cnblogs.com/shouhuxianjian/p/18254025

相关文章

  • (26-4-02)基于OpenAI和LangChain的上市公司估值系统:OpenAI API和Langchain探索(2)Langch
    10.5.2 Langchain和OpenAI处理编写文件summarizer.py,定义了使用Langchain和OpenAI处理文本和文档的功能处。其中,类UnstructuredStringLoader用于加载未结构化的字符串内容,将其分割成适当大小的块。方法split_text_in_chunks和方法split_doc_in_chunks分别用于将文本......
  • Elasticsearch 近实时搜索的底层原理
    我们都知道Elasticsearch的搜索是近实时的,数据写入后,立即搜索(不通过id)文档是搜不到的。这一切的原因要归于lucene所提供的API,因为lucene的API就是非实时的,Elasticsearch在lucene之上盖房子,通过一些增强,实现了查询的近实时和id查询的实时性。本文就来看看这个近实时......
  • AOP切面的实现原理【底层源码】
    AOP是基于IOC的Bean加载来实现的,将切面类的所有切面方法根据使用的注解生成对应的Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor,为后续交给代理增强实现做准备这里我们可以很明确的知道,AOP也是在Bean容器中被Spring管理的,根据初始化过程打断点定位......
  • AOP代理的创建【底层源码】
    代理的创建(源码)创建代理的方法是postProcessAfterInitialization:如果Bean被子类标识为代理,则使用配置的拦截器创建一个代理源码参考:AOP切面底层原理【底层源码】-postProcessAfterInitialization源码部分wrapIfNecessary方法主要用于判断是否需要创建代理,如果bean能......
  • 告密者斯诺登:永远不要信任 OpenAI 或其 ChatGPT 等产品|TodayAI
    为什么 OpenAI 变得越来越难以信任OpenAI,一家以开发先进人工智能技术而闻名的公司,正面临越来越多的信任危机。近期,一些令人不安的迹象使人们对这家公司的透明度和安全性产生了质疑。首先,在OpenAI的旧金山办公室外,有一些身份不明的秘密保安人员,这些人的出现给当地社区带......
  • 1、docker-安装-阿里云镜像加速-docker工作流程和底层原理
    1、访问官网:https://docs.docker.com/get-docker/2、卸载旧版本:yumremovedocker\docker-client\docker-client-latest\docker-common\docker-latest\docker-latest-lo......
  • 超级底层:10WQPS/PB级海量存储HBase/RocksDB,底层LSM结构是什么?
    文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录博客园版为您奉上珍贵的学习资源:免费赠送:《尼恩Java面试宝典》持续更新+史上最全+面试必备2000页+面试必备+大厂必备+涨薪必备免费赠送:《尼恩技术圣经+高并发系列PDF》,帮你实现技术自由,完成职业升级,薪......
  • 双列集合 HashMap以及TreeMap底层原理
    双列集合 特点:    双列集合一次需要存一对数据,分别为键和值    键不能重复,值可以重复    键和值是一一对应的,每个键只能找到自己对应的值        键和值这个整体在Java中叫做“Entry对象”Map的常见API    Map是双列集合的顶......
  • C++双端队列deque源码的深度学习(stack,queue的默认底层容器)
    什么是deque?deque是C++标准模板库(STL)中的一个容器,代表“双端队列”(double-endedqueue)。deque支持在其前端(front)和后端(back)进行快速插入和删除操作,并且它在序列的中间插入和删除元素时通常比vector或list更高效。deque的特点双端插入和删除:你可以在deque的头部和尾部快速......
  • (26-4-01)基于OpenAI和LangChain的上市公司估值系统:OpenAI API和Langchain探索(1)OpenAI
    10.5 OpenAIAPI和Langchain探索接下来使用OpenAIAPI与Langchain对解析后的文档进行总结,从中提取有价值的信息。这将帮助我们更好地理解文档中的内容,包括业务情况、风险因素、财务状况分析等,并提供更简洁的概括信息。10.5.1 OpenAI接口编写文件openai_interface.py,实......