gocqhttp + chatgpt + stable diffusion实现AI聊天画图机器人

编程知识 更新时间:2023-05-02 03:07:50

1、需要准备的是:gocqhttp https://github/Mrs4s/go-cqhttp/releases

                        chatgpt账号,用于申请API

                        stable diffusion webui-colab,最好选v1-4版本的,否则可能会出现内存不足 链接

                         colab免费GPU服务器

2、配置gocqhttp在本地电脑运行。

        我们使用HTTP端口,教程:前往教程

        配置好了之后,我们开始写python代码,下面是我写的用于接收QQ消息的代码main.py

from flask import Flask, request
import api
from queue import Queue
import threading
from chatgptAPI import reply, translate

app = Flask(__name__)
request_queue = Queue()


def process_request():
    while True:
        # 从队列中取出请求消息
        data = request_queue.get()
        try:
            if data['message_type'] == 'group':  # 如果是群聊信息
                cq = data['raw_message']  #获取带cq码的消息字段
                if cq[1:6] == 'CQ:at' and cq[10:20] == '#qq_id':#根据QQ号长度修改cq中的数字
                    gid = data['group_id']  # 获取群号
                    at_user_id = data['sender']['user_id']      #获取@你的人是谁
                    at_message_text = cq[22:]      #提取文本部分,根据QQ号长度修改cq中的数字
                    if len(at_message_text) > 500:          
                        api.keyword("抱歉,字数过长", at_user_id, gid)
                    else:
                        print(at_message_text, end='\n')
                        if at_message_text[0] == '%':         #如果是%则是AI绘画功能
                            prompt = '%' + translate(at_message_text[1:])  #使用chatgpt去把需求转化成prompt
                            api.keyword(prompt, at_user_id, gid)
                        else:                                    #否则就是chatgpt功能
                            message = reply(at_message_text)     #reply去调用chatgpt
                            print(message)
                            api.keyword(message, at_user_id, gid)

            #以下是处理私聊信息
            if data['message_type'] == 'private' and data['raw_message'][0] == '#':
                uid = data['sender']['user_id']
                raw_message = data['raw_message'][1:]
                if len(raw_message) > 2500:
                    api.keyword("抱歉,提问字数过长", uid, gid=None)
                else:
                    print(raw_message)
                    try:
                        message = reply(raw_message)
                        print(message)
                        api.keyword(message, uid, gid=None)
                    except:
                        api.keyword("api失效了喵~", uid, gid=None)
                        print("api失效了喵~")

            if data['message_type'] == 'private' and data['raw_message'][0] == '%':
                uid = data['sender']['user_id']
                raw_message = data['raw_message']
                if len(raw_message) > 500:
                    api.keyword("抱歉,提问字数过长", uid, gid=None)
                else:
                    print(raw_message)
                    prompt = translate(raw_message[1:])
                    print(prompt)
                    message = '%' + prompt
                    api.keyword(message, uid, gid=None)

        except:
            pass

        # 标记请求消息已处理完成
        request_queue.task_done()


# 启动后台处理线程
thread = threading.Thread(target=process_request)
thread.daemon = True
thread.start()


@app.route('/', methods=["POST"])
def post_data():
    # 将请求消息加入队列,一个一个处理,主要防止画图请求过多,把GPU显存弄爆
    data = request.get_json()
    request_queue.put(data)
    return 'OK'


if __name__ == '__main__':
    app.run(debug=False, host='127.0.0.1', port=5701)

接下来,我们就要去api.py中去写如何去处理消息的代码了。写得很乱,应该在此处去区分调用的是回复功能还是绘画功能。但是我懒得改了

import requests
import base64
from PIL import Image
from io import BytesIO
from stablediffusionAPI import draw


def keyword(message, uid, gid):
    if gid is not None:
        if message[0] == '%':                 #如果是%则去绘画
            base64Code = draw(message[1:])    #去调用AI绘画的功能
            send_image(uid, gid, base64Code)
        else:
            message = '[CQ:at,qq=' + str(uid) + ']' + str(message)   #at别人
            requests.get(url='http://127.0.0.1:5700/send_group_msg?group_id=%s&message=%s' % (gid, message))
    if gid is None:
        if message[0] == '%':
            base64Code = draw(message[1:])
            send_image(uid, gid, base64Code)
        else:
            requests.get(url='http://127.0.0.1:5700/send_private_msg?user_id=%s&message=%s' % (uid, message))


def send_image(uid, gid, base64Code):         #发送图片消息
    if gid is None:
        url = 'http://127.0.0.1:5700/send_private_msg'
        data = {
            "user_id": str(uid),
            "message": "[CQ:image,file=base64://" + base64Code + ",type=show,id=40000]"
        }
    else:
        url = 'http://127.0.0.1:5700/send_group_msg'
        data = {
            "group_id": str(gid),
            "message": "[CQ:image,file=base64://" + base64Code + "]"
        }
    headers = {"Content-Type": "application/json"}
    requests.post(url=url, json=data, headers=headers)

接下来,就是去完成具体的功能了,首先我们去写回复功能,去调用chatgpt的api。我们新建一个chatgptAPI.py去写

import openai     #直接pip install openai就行了
openai.api_key = 'your api_key'   #去openai官网申请你的API私钥

#回复功能
def reply(message):            
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",         #选择gpt-3.5模型
        #这这里给gpt洗脑
        messages=[
            # {"role": "user", "content": "你是一只猫娘,请用撒娇的语气回复我的问题,并在结尾加上喵~"},
            # {"role": "user", "content": "请你以精简的语句回复我"},
            {"role": "user", "content": message}
        ]
    )
    response = response['choices'][0]['message']['content']      #获取回复中的文本
    return response

#需求转prompt功能
def translate(message):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": "xxxxxxxx"      #下面会给出洗脑文本,替换里面的xxxx
             }
        ]
    )
    response = response['choices'][0]['message']['content']
    return response


if __name__ == '__main__':
    print(translate("一个美丽的女孩"))   #简单一个测试

下面是二次元图片的洗脑暗号

StableDiffusion是一款利用深度学习的文生图模型,支持通过使用提示词来产生新的图像,描述要包含或省略的元素。
我在这里引入StableDiffusion算法中的Prompt概念,又被称为提示符。
下面的prompt是用来指导AI绘画模型创作图像的。它们包含了图像的各种细节,如人物的外观、背景、颜色和光线效果,以及图像的主题和风格。这些prompt的格式经常包含括号内的加权数字,用于指定某些细节的重要性或强调。例如,'(masterpiece:1.5)'表示作品质量是非常重要的,多个括号也有类似作用。此外,如果使用中括号,如'{blue hair:white hair:0.3}',这代表将蓝发和白发加以融合,蓝发占比为0.3。
以下是用prompt帮助AI模型生成图像的例子:(masterpiece:1.2, best quality), (finely detailed beautiful eyes: 1.2), ((1girl)), ((solo)), (red eyes:1.4), (finely detailed eyes and detailed face:1.3), (beautiful and clear background:1.2), (extremely detailed CG, ultra-detailed, best shadow:1.1), ((depth of field)), ((watercolor)), (oni:1.5), (kimono:1.3), large breasts, bare shoulders, flowers and petals, beautiful concept illustration, (white background:0.5), (illustration:1.1), (extremely fine and beautiful:1.1), (perfect details:1.1), from side, cowboy shot,


可以选择的prompt包括:

着装
    kimono(和服)
    school uniform(校服)
    miko  (巫女)
    
五官
    finely detailed eyes (精致的眼镜)
    detailed face    (精致的脸)
    pink hair   (粉头发)

身材
    large breasts
    bare shoulders

背景
    clear       (干净的)
    beautiful     (美丽的)
    white background (白色背景)
    High contrast   (高对比度)

仿照例子,并不局限于我给你的单词,给出一套详细描述'此处替换成收到的message'的prompt,注意:masterpiece,(bestquality),highlydetailed,ultra-detailed,1 girl,必须放在前面,prompt不能超过80个。直接开始给出prompt不需要用自然语言描述。 

我们很轻松地就完成了调用chatgpt的功能,接下来是部署stable diffusion。此处开始需要在colab上开启shtable diffusion的api(如果自己的电脑够好,可以在本地部署)

首先点开colab笔记本,可以用官方的,也可以用我的:colab笔记本

根据注释修改,按照顺序运行就行了,不过要注意第一个单元格启动时,开启的不是api,是webui,主要是用来下载一些所需的东西,下载完了需要停止运行。如下图所示:

 先点击运行,然后耐心等待至加载到启动gradio

到这就可以停止单元格了,需要的东西都下载好了。然后就是按照顺序,去下载你想要使用的模型。重点来了:修改webui.py中的代码,按照注释来就行了。

 去ngrok官网获取我们的api_key

在 --ngrok 中加入你的api_key,--ckpt 中加入模型的路径,然后就可以愉快地运行了

 现在我们已经在服务器上开启了api并映射到了公网,复制红框中的url,开始写stable_diffusion.py

import json
import requests
import io
import base64
from PIL import Image, PngImagePlugin

url = " "  #刚刚获取的url


def draw(message):
    payload = {                        #stable diffusion的参数
        "prompt": message,
        "steps": 20,             
        "negative_prompt": "(worst quality, low quality:1.4), monochrome, zombie,",
        "cfg_scale": 7,
        "sampler_index": 'DPM++ 2M Karras'
    }
    response = requests.post(url=f'{url}/sdapi/v1/txt2img', json=payload)
    r = response.json()
    return r['images'][0]         #返回base64字符串


if __name__ == '__main__':                 #简单一个测试
    draw("a girl,long hair,school")

现在我们开启gocqhttp监听QQ消息,开启main.py的API处理监听到的消息。

在执行到stable diffusion API的时候,colab中可能出现下面的错误:

没有关系,我也在colab笔记本写了怎么处理这个问题,按照注释来修改行。

一切问题都OK,启动gocqhttp,启动main.py,启动colab上的API!下面来看看效果:

 

非常OK! 

更多推荐

gocqhttp + chatgpt + stable diffusion实现AI聊天画图机器人

本文发布于:2023-04-25 10:53:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/0371b40405c584648a3f43e141c1c8d8.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:画图   机器人   chatgpt   gocqhttp   stable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!

  • 102929文章数
  • 26172阅读数
  • 0评论数