当前位置:   article > 正文

【多模态大模型开发】调用自己的AIGC 打通stable diffusion 自己lora图片_flask 封装多模态大模型

flask 封装多模态大模型

先上图

!

如何实现

1、板子发送post请求。stable diffusion webui 这边图片默认是512\\_512 .板子内存有限。需要flask 接收图片后进行一次缩放到240\\_240.(未填充满,这个RTOS的开发板资源太紧张了)

ps:都在本地。webui可以部署到云服务器。

2、webui 使用lora 调整图片风格,还有 lcm 加快出图速度。正常是20step 出图,加上lcm 可以4-6step 出图

python webui.py --port 8903 --xformers --share --device-id 1 --api --listen

3.flask 服务器中转调用webui

time curl -X POST http://10.162.88.10:5000/post -H "Content-Type: application/json" -d '{"prompt":"dog"}'

单3090显卡 4G 显存占用出图时间0.5s

聆思大模型AI开发套件

开发环境搭建

安装lisa工具包

  1. wget -qO- https://cdn.iflyos.cn/public/cskTools/lisa-zephyr-install-v2.sh | bash
  2. lisa info zephyr

下载源码

git clone --branch v1.6.0 https://cloud.listenai.com/CSKG962172/duomotai_ap

初始化

  1. lisa zep init-app
  2. lisa zep update

编译工程

lisa zep build -b csk6\\\_duomotai\\\_devkit apps\LLM\\\_control -p

板子下载程序

lisa zep exec cskburn -s .\COM54 -C 6 -b 1500000 0x000000 Z:\06\\\_iot\07\\\_lisa\duomotai\\\_ap\build\zephyr\zephyr.bin

总体评价 简洁,快速,多平台,点赞。。

使用linux gpu 服务器编译。然后windows samba服务下载。

代码修改

1.使用串口触发post请求

\\\`

static void cmd\\\_aigc\\\_sdwebui(const struct shell shell, size\\\_t argc, char *argv)

{

  1. if(argc != 2 || argv == NULL){
  2.     LOG_ERR("cmd_aigc_sdwebui error, argc = %d, argv = %p", argc, argv);
  3.     return;
  4. }
  5. char *prompt = argv[1];
  6. LOG_INF("YYJJ cmd_aigc_sdwebui = %s", prompt);
  7. int ret = 0;
  8. uint8_t *out_data = NULL;
  9. int out_len = 0;
  10. //char png_download_url[256= "http://10.162.88.10:5000/output/dog_20240319153542.png";
  11. char png_download_url[256];
  12. int ret = app_aigc_post("http://10.162.88.10:5000/post", prompt, &png_download_url);
  13. if(ret == 0)
  14. {
  15.     uint8_t *out_data = NULL;
  16.     int out_len = 0;
  17.     int ret = app_download(png_download_url, &out_data&out_len);
  18.     if(ret != 0){
  19.         LOG_ERR("app download failed: %d", ret);    
  20.     }else{
  21.         LOG_INF("app download succeeded: addr: %p, len: %d", (void *)out_data, out_len);
  22.         if((out_len != 0&& (out_data != NULL)){
  23.             ui_set_img(out_data, out_len);
  24.             csk_free(out_data);
  25.         }
  26.     }
  27. }

}

  1. #define AIGC_SD_PROMPT_TEXT     "<wifi> aigc sd prompt text"
  2. SHELL_STATIC_SUBCMD_SET_CREATE(sub_wifi,
  3.                     SHELL_CMD_ARG(connect,         NULL, WIFI_CONNECT_TEXT,     cmd_wifi_connect,     30),
  4.                        SHELL_CMD_ARG(disconnect,     NULL, WIFI_DISCONNECT_TEXT, cmd_wifi_disconnect,10),
  5.                        SHELL_CMD_ARG(add,             NULL, WIFI_ADD_TEXT,         cmd_wifi_add,         30),
  6.                        SHELL_CMD_ARG(delete,         NULL, WIFI_DELETE_TEXT,     cmd_wifi_delete,     20),
  7.                     SHELL_CMD_ARG(list,         NULL, WIFI_LIST_TEXT,         cmd_wifi_list,         10),
  8.                     SHELL_CMD_ARG(aigc,         NULL, AIGC_SD_PROMPT_TEXT,     cmd_aigc_sdwebui,     20),
  9.                        SHELL_SUBCMD_SET_END
  10. );~~~~
  11. `
  12. 2.获取下载地址
  13. `int parse_json_response(const char *response_buf, char **aigc_url) {
  14.     // 参数校验
  15.     if (response_buf == NULL || aigc_url == NULL) {
  16.         return -1// 无效参数
  17.     }
  18.     // 解析JSON
  19.     cJSON *json = cJSON_Parse(response_buf);
  20.     if (json == NULL) {
  21.         const char *error_ptr = cJSON_GetErrorPtr();
  22.         if (error_ptr != NULL) {
  23.             fprintf(stderr, "Error before: %s\n"error_ptr);
  24.         }
  25.         return -1// 解析失败
  26.     }
  27.     cJSON *file_url = cJSON_GetObjectItemCaseSensitive(json, "file_url");
  28.     if (cJSON_IsString(file_url) && (file_url->valuestring != NULL)) {
  29.         *aigc_url = strdup(file_url->valuestring);
  30.         cJSON_Delete(json); 
  31.         return 0
  32.     } else {
  33.         cJSON_Delete(json); 
  34.         return -1
  35.     }
  36. }
  37. int app_aigc_post(const char *url, char * prompt , uint8_t **aigc_url)
  38. {
  39.     int ret = 0;
  40.     int client_socket = -1;
  41.     if(url == NULL){
  42.         LOG_ERR("%s: %d", __FUNCTION__, __LINE__);
  43.         return -1;
  44.     }
  45.     ret = http_parse_url(&http_client, url);
  46.     if(ret < 0){
  47.         LOG_ERR("%s: %d", __FUNCTION__, __LINE__);
  48.         return ret;
  49.     }
  50.     client_socket = connect_socket(http_client.host, http_client.port);
  51.     if(client_socket < 0){
  52.         LOG_ERR("%s: %d", __FUNCTION__, __LINE__);
  53.         ret = client_socket;
  54.         goto failed;
  55.     }
  56.     char req_buf[128= "{\"prompt\":\" dog \"}"// 根据需要修改负载
  57.     scanf(req_buf,"{\"prompt\":\" %s \"}",prompt);
  58.     size_t req_buf_len = strlen(req_buf);
  59.     LOG_INF("Start Post");
  60.     char *response_buf = csk_malloc(MAX_IAMGE_SIZE);
  61.     if(!req_buf){
  62.         LOG_ERR("%s: %d", __FUNCTION__, __LINE__);
  63.         close(client_socket);
  64.         ret = -1;
  65.         goto failed;
  66.     }
  67.     struct http_request req = {
  68.         .method = HTTP_POST,
  69.         .url = "/post"// Flask定义的路径
  70.         .host = "10.162.88.10",
  71.         .protocol = "HTTP/1.1",
  72.         .header_fields = (const char *[]){"Content-Type""application/json"NULL},
  73.         .response = response_aigc_cb,
  74.         .recv_buf = response_buf,
  75.         .recv_buf_len = MAX_IAMGE_SIZE,
  76.         .payload = req_buf,
  77.         .payload_len = req_buf_len,
  78.     };
  79.     ret = http_client_req(client_socket, &req, 5000"IPv4 POST");
  80.     if(ret < 0){
  81.         LOG_ERR("%s: %d", __FUNCTION__, __LINE__);    
  82.     }
  83.     close(client_socket);
  84.     ret = k_sem_take(&http_rsp_sem, K_SECONDS(10));
  85.     if(ret != 0){
  86.         LOG_ERR("get image timeout: %d", ret);
  87.         goto closed;
  88.     }
  89.     parse_json_response(response_buf, aigc_url);
  90. closed:
  91.     if(response_buf) csk_free(response_buf);
  92. failed:
  93.     if(http_client.scheme) csk_free(http_client.scheme);
  94.     if(http_client.host) csk_free(http_client.host);
  95.     if(http_client.path) csk_free(http_client.path);
  96.     memset(&http_client, 0, sizeof(http_client_handle_t));
  97.     return ret;
  98. }
  99. `
  100. 3.下载并且显示
  101. `
  102.         int ret = app_download(png_download_url, &out_data&out_len);
  103.         if(ret != 0){
  104.             LOG_ERR("app download failed: %d", ret);    
  105.         }else{
  106.             LOG_INF("app download succeeded: addr: %p, len: %d", (void *)out_data, out_len);
  107.             if((out_len != 0&& (out_data != NULL)){
  108.                 ui_set_img(out_data, out_len);
  109.                 csk_free(out_data);
  110.             }
  111.         }
  112. `

\\`\\`

\\`

中间框架 flask

stable diffusion webui 接口

post 和get 方法。

代码较少。直接全部贴源码

\`

from flask import Flask, request, jsonify, url\_for

import datetime

import base64

import os

import requests

import json

from PIL import Image

import ioapp = Flask(\_\_name\_\_)

from flask import send\_from\_directorydef save\_encoded\_image(b64\_image: str, output\_path: str):

  1. """
  2. Save the given image to the given output path.
  3. :param b64_image:  base64 encoded image
  4. :param output_path:  output path
  5. :return:  None
  6. """
  7. # 判断当前目录下是否存在 output 文件夹,如果不存在则创建
  8. if not os.path.exists("output"):
  9.     os.mkdir("output")
  10. timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
  11. output_path = f"{output_path[0:5]}_{timestamp}" + ".png"
  12. # 将文件放入当前目录下的 output 文件夹中
  13. output_path = f"output/{output_path}"
  14. # Decode the base64 image
  15. image_data = base64.b64decode(b64_image)
  16. image = Image.open(io.BytesIO(image_data))
  17. # Resize the image
  18. image = image.resize((240240), Image.ANTIALIAS)
  19. # Save the resized image
  20. image.save(output_path)
  21. print(output_path)
  22. return output_path

def webui\_txt2img(prompt='dog'):

  1. txt2img_url = "http://10.162.89.10:8903/sdapi/v1/txt2img" # 服务器地址
  2. prompt_lora_lcm = prompt + r", <lora:PixelStyle:1>,<lora:pytorch_lora_weights:1>"
  3. data = {
  4.     'prompt': prompt_lora_lcm,
  5.     'negative_prompt''',
  6.     "sampler_index""LCM",
  7.     'width'512,
  8.     'height'512,
  9.     "steps"6,
  10.     "cfg_scale"1.5,
  11. }
  12. print(data)
  13. response = requests.post(txt2img_url, data=json.dumps(data))
  14. image_path = save_encoded_image(response.json()['images'][0], prompt) 
  15. return image_path

@app.route('/post', methods=['POST'])

def handle\_post():

  1. data = request.json
  2. print(data)
  3. if not data or 'prompt' not in data:
  4.     return jsonify({"error""Missing 'prompt' field"}), 400
  5. prompt = data['prompt']
  6. print(f"Received prompt: {prompt}")
  7. image_file_name = webui_txt2img(prompt)
  8. root_url = request.url_root.rstrip('/')  # 移除尾部的斜杠(如果有的话)
  9. file_url = f'{root_url}/{image_file_name}'
  10. return jsonify({"file_url"file_url})

@app.route('/output/<path:filename>')

def custom\_static(filename):

return send_from_directory('output', filename)

if name == '\_\_main\_\_':

app.run(host='0.0.0.0', port=5000, debug=True)

\`

!

总结

上手体验快。同级别芯片对比乐鑫只有不好用的chatgpt。总体来说资源太紧了,建议加大psram。

后续弄一下LVGL,添加chagpt,完成lvgl,然后语音转文字,tts。然后开源出来。。

分享来自社区博主甴尐 ,原文链接:【聆思大模型AI开发套件】调用自己的AIGC 打通stable diffusion 自己lora图片

开发板资料:套件简介 | 聆思文档中心

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/801875
推荐阅读
相关标签
  

闽ICP备14008679号