Ollama+FastAPI+React手把手构建自己的本地大模型,支持SSE

最近大家都在玩LLM,我也凑了热闹,简单实现了一个本地LLM应用,分享给大家,百分百可以用哦~^ - ^

先介绍下我使用的三种工具:

  • Ollama:一个免费的开源框架,可以让大模型很容易的运行在本地电脑上
  • FastAPI:是一个用于构建 API 的现代、快速(高性能)的 web 框架,使用 Python 并基于标准的 Python 类型提示
  • React:通过组件来构建用户界面的库

简单来说就类似于LLM(数据库)+FastAPI(服务端)+React(前端)

开始搭建

1、下载Ollama之后使用Ollama完成大模型的本地下载和的运行

ollama run llama3:8b

这里我下载了最新的llama3:8b,电脑配置不高的话10b以内可以无痛运行,当然啦你也可以多下几个大模型,对比一下,我还下载了qwen,对比下来同一模型越大越聪慧,国内模型对中文支持度普遍好一点。

2、模型运行之后就可以调用了

curl http://localhost:11434/api/generate -d '{
     
"model": "llama3:8b",  
"prompt": "Why is the sky blue?",  
"stream": false  
}'

3、新建一个python项目,实现代码如下:

import uvicorn
from fastapi import FastAPI, Request, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import json
import requests
from sse_starlette.sse import EventSourceResponse
import asyncio
import aiohttp

app = FastAPI(debug=True)

origins = [
    "http://localhost",
    # 输入自己前端项目的地址
]

# 设置跨域
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

urls = ["http://localhost:11434/api/generate"]


llm_list = [ {'label': 'qwen:latest', "value": 'qwen:latest'},
            {'label': 'llama3:8b', "value": 'llama3:8b'}, ]

# 获取模型列表
@app.get("/llm/list")
def read_llm(model: str = 'qwen:latest'):
    return {"data": llm_list}


# 这是一个异步生成器函数,它发送请求到 Ollama,并逐行读取响应内容,生成事件流。
async def stream_ollama_response(model_name, prompt):
    if model_name:
        url = urls[0]
        payload = {
            "model": model_name,
            "prompt": prompt,
            "stream": True
        }
        async with aiohttp.ClientSession() as session:
            async with session.post(url, json=payload) as response:
                async for line in response.content:
                    if line:
                        data = line.decode('utf-8').strip()
                        if data:
                            yield {"event": "message", "data": json.loads(data)["response"]}


# 开始对话,接收 model_name 和 prompt 参数。它调用 event_generator 函数,启动与 Ollama 的交互,并通过 EventSourceResponse 返回事件流
@app.get("/chat")
async def generate(request: Request, model_name: str = 'qwen:latest',
                   prompt: str = '请用中文介绍下中国古代四大名著之一的《红楼梦》'):
    async def event_generator():
        async for event in stream_ollama_response(model_name, prompt):
            yield event
            if await request.is_disconnected():
                break

    return EventSourceResponse(event_generator())


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

这是用SSE形式实现流式输出的demo,下一篇我再讲讲如何用WebSocket实现。

4、新建一个react项目,我用了antd大礼包+@microsoft/fetch-event-source这个微软的sse插件实现,代码如下:

import {
    Input, Dropdown, Select, Form, Button, Space } from 'antd';
import {
    useEffect, useState } from 'react';
import {
    getList, chat } from './service';
import {
    useRequest } from '@umijs/max';
import {
    fetchEventSource } from '@microsoft/fetch-event-source';

const {
    TextArea } = Input;

# 不能走代理哦,走了代理流式就失效了,?- ?
export const getHost = () => 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值