在上一节课我们学习了 AI模型的选择与部署
基于Gradio的AI应用搭建实践课③:AI模型部署与推理:应用功能可无限拓展
核心内容包括:
在魔搭上搜索模型
使用Notebook环境运行模型
使用 SwingDeploy部署模型API
通过这些学习,我们能够更加系统化和高效地选择合适的 AI模型,并顺利完成从模型选择到部署再到推理的整个流程,为实现应用功能的无限拓展提供了坚实的技术支撑。
接下来,我们将打通前后端的任督二脉,完成前后端联调及应用发布。
一、背景
在【Gradio组件学习:应用UI界面可无限DIY】课程中,我们学习了如何使用Gradio方便地搭建一些前端页面,实现包括文本、图像、音视频等各种类型的输入和输出的界面搭建。在【AI模型部署与推理:应用功能可无限拓展】课程中,我们学习了在魔搭平台搜索合适的模型,并通过多种方式验证模型的效果,包括在Notebook中运行模型、使用SwingDeploy部署模型API等。
本次课程,我们将结合前两个课程的内容,综合使用Gradio和模型推理,将AI模型实际搭建成为一个可以使用的AI应用,并发布为可用的创空间。
二、课程目标
在本节课中,你将学习:
1、基于Gradio和大语言模型搭建「聊天机器人」(文本输入,聊天框文本输出)
2、基于Gradio、大语言模型、文本转语音模型搭建「带有语音回复的聊天机器人」(文本输入,聊天框文本+音频输出),并将此应用发布到创空间(使用魔搭的免费CPU资源)。
3、基于Gradio、文生图模型,搭建「文生图」应用(文本输入,图片输出),并将此应用发布到创空间(使用魔搭的免费xGPU资源)
三、课程内容
Notebook可以在这个链接中直接运行:
https://modelscope.cn/notebook/share/ipynb/292eea82/studio_example.ipynb
1、前置操作
Notebook是ModelScope提供的免费计算资源,可以通过登录并编码的方式进行模型的体验。
可以通过如下的方式进行体验:
1. 首先需要将您的modelscope账号绑定阿里云账号,详细文档参考:https://www.modelscope.cn/docs/notebooks/free-trial
2. 进入首页->我的Notebook,可以根据模型的大小选择GPU或CPU实例,点击启动Notebook
预装如下依赖
!pip install gradio==5.4.0 openai modelscope_studio
2、聊天机器人
下面我们展示使用大语言模型,构建一个聊天机器人。我们使用Modelscope平台提供的模型推理API,快速上手功能验证。https://modelscope.cn/docs/model-service/API-Inference/intro
Modelscope平台提供的模型推理API兼容OpenAI协议,可以在Python中使用OpenAI的client调用。
# 仅在 Notebook 中运行时需要,本地运行无需该部分
import os
os.environ['GRADIO_ROOT_PATH'] = f"/{os.environ['JUPYTER_NAME']}/proxy/7860"
print(os.environ['GRADIO_ROOT_PATH'])
import gradio as gr # 导入 Gradio 库,用于构建和部署 Web 应用程序
from openai import OpenAI # 导入 OpenAI 库,用于访问 Modelscope 的 API
import os # 导入 os 库,用于访问环境变量
# 初始化 OpenAI 客户端
client = OpenAI(
api_key=os.getenv("MODELSCOPE_ACCESS_TOKEN"), # 从环境变量中获取 Modelscope API 密钥,即个人SDK token
base_url="https://api-inference.modelscope.cn/v1" # 设置基础 URL为 Modelscope API地址
)
# 仅在 Notebook 中运行时需要,本地运行无需该部分:检查是否已存在名为 `app` 的 Gradio 应用
try:
app.close() # 如果 `app` 存在,则关闭它
except NameError:
# 如果 `app` 不存在,捕获 NameError 异常,并忽略该异常
pass
# 创建 Gradio 应用程序
with gr.Blocks() as app: # 使用 Gradio 的 Blocks 创建新的应用
gr.Markdown("# Chat with history") # 使用 Markdown 添加标题
chatbot = gr.Chatbot(type="messages") # 创建一个聊天机器人组件,用于显示消息历史
input = gr.Textbox(show_label=False) # 创建一个文本框组件,用于输入用户信息
# 定义聊天函数,支持历史消息处理和流式输出
def chat(prompt, messages):
# 打印当前的聊天记录
print(messages)
# 将用户的输入添加到消息记录中
messages.append({'role': 'user', 'content': prompt})
# 使用 yield 返回初始状态以开始流式响应
yield '', messages
try:
# 调用 OpenAI 的聊天接口,启动流模式获取响应
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct", # 指定使用的 OpenAI 模型
messages=messages, # 传入当前的消息记录
stream=True # 开启流式响应
)
# 逐步处理来自流响应的数据
full_response = "" # 初始化完整响应
messages.append({'role': 'assistant', 'content': full_response}) # 为助手的响应添加占位
for chunk in response: # 迭代响应流的每个块
content = chunk.choices[0].delta.content # 获取当前数据块的内容
full_response += content # 将新的内容追加到完整响应
messages[-1]['content'] = full_response # 更新历史记录中的助手内容
# 使用 yield 实时更新使用界面的显示
yield '', messages
except Exception as e:
# 如果请求失败,捕获异常并返回错误信息
yield str(e)
# 当用户提交输入时,调用 `chat` 函数,并实时更新聊天记录
input.submit(fn=chat, inputs=[input, chatbot], outputs=[input, chatbot])
# 启动 Gradio 应用程序,设置服务器端口为 7860
app.launch(server_port=7860)
3、带有语音回复的聊天机器人
我们可以将大模型与TTS(文本转语音)技术结合,就可以让大模型输出文本后,用语音给我们播报。
首先我们验证单独的语音合成功能,使用魔搭社区的语音合成模型:https://modelscope.cn/models/iic/speech_sambert-hifigan_tts_zh-cn_16k
from modelscope.outputs import OutputKeys # 导入 OutputKeys,用于访问输出结构中的特定组件
from modelscope.pipelines import pipeline # 导入 pipeline,用于创建处理任务的管道
from modelscope.utils.constant import Tasks # 导入 Tasks,包含任务类型的常量定义
# 指定要使用的模型 ID,这里是一个中文语音合成模型
model_id = 'iic/speech_sambert-hifigan_tts_zh-cn_16k'
# 创建一个文本到语音的处理管道,指定任务类型为文本到语音,并使用指定的模型
sambert_hifigan_tts = pipeline(task=Tasks.text_to_speech, model=model_id)
# 要合成的文本
text = '今天天气很晴朗'
# 使用管道处理输入文本,指定使用的语音风格为 'zhitian_emo'
output = sambert_hifigan_tts(input=text, voice='zhitian_emo')
# 从输出中提取生成的 WAV 音频数据
wav = output[OutputKeys.OUTPUT_WAV]
# 将生成的音频数据写入一个 WAV 文件
with open('output.wav', 'wb') as f:
f.write(wav) # 以二进制形式写入音频文件
# 使用这段代码在notebook中播放保存的音频文件
from IPython.display import Audio, display
audio = Audio(filename='output.wav')
display(audio)
以下代码将对话和转音频相结合,构建了一个gradio应用。
import gradio as gr # 导入 Gradio 库,用于创建 Web 应用
from openai import OpenAI # 导入 OpenAI 库,用于使用 Modelscope 的 API
import os # 导入 os 模块,用于处理文件系统路径和环境变量
import datetime # 导入 datetime 模块,用于处理日期和时间
import modelscope_studio.components.base as ms
import modelscope_studio.components.legacy as legacy
from modelscope.outputs import OutputKeys # 导入 OutputKeys,用于处理输出的关键字
from modelscope.pipelines import pipeline # 导入 pipeline 用于创建 AI 管道
from modelscope.utils.constant import Tasks # 导入 Tasks,包含常见任务类型的常量定义
# 初始化 OpenAI 客户端
client = OpenAI(
api_key=os.getenv("MODELSCOPE_ACCESS_TOKEN"), # 从环境变量中获取 Modelscope API 密钥,即个人Modelscope SDK token
base_url="https://api-inference.modelscope.cn/v1" # 设置基础 URL为 Modelscope
)
# 定义文本到语音合成的模型 ID,并创建相应的处理管道
model_id = 'iic/speech_sambert-hifigan_tts_zh-cn_16k'
sambert_hifigan_tts = pipeline(task=Tasks.text_to_speech, model=model_id)
# 创建用于保存音频文件的目录
directory_path = "output_wavs"
if not os.path.exists(directory_path):
os.makedirs(directory_path) # 如果目录不存在,则创建该目录
# 定义函数,用于解析资源路径,将相对路径转换为绝对路径
def resolve_assets(relative_path):
return os.path.join(os.getcwd(), "./output_wavs", relative_path)
# 将消息转换为可在 Chatbot 组件中显示的格式
def messages_to_chatbot(messages, disable_flush=False):
history = []
# 迭代处理成对的消息,交替处理用户和助手的消息
for q, r in zip(messages[0::2], messages[1::2]):
# 创建一个包含用户和助手消息的列表,并根据需求决定是否禁用刷新
history.append([{'text': q['content']}, {'text': r['content'], 'flushing': not disable_flush}])
return history
# 仅在 Notebook 中使用需要以下代码,如果之前已经定义过 `app`,关闭它
try:
app.close()
except NameError:
# 如果 `app` 不存在,忽略这个异常
pass
# 创建 Gradio 应用
with gr.Blocks() as app: # 使用 Gradio 的 Blocks 创建新的应用
with ms.Application():
gr.Markdown("# Chat And TTS") # 使用 Markdown 添加应用标题
chatbot = legacy.Chatbot(value=[], height=300) # 创建聊天机器人组件,设置初始为空,指定高度
input = gr.Textbox(show_label=False) # 创建一个输入框用于文本输入
history = gr.State([]) # 创建一个状态用于存储聊天历史
# 定义聊天函数,支持历史消息处理和流式输出
def chat(prompt, history):
# 将用户输入添加到历史中,并生成初始输出
history.append({'role': 'user', 'content': prompt})
yield '', history, messages_to_chatbot(history)
try:
# 调用 OpenAI API 进行聊天,启用流式响应
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct", # 使用指定的 OpenAI 模型
messages=history, # 传入当前的消息历史
stream=True # 启用流式输出
)
# 处理流式响应并逐步更新聊天记录
full_response = "" # 初始化完整的响应
history.append({'role': 'assistant', 'content': full_response}) # 在历史中添加助手响应占位
for chunk in response: # 迭代收到的流块
content = chunk.choices[0].delta.content # 获取当前块的文本内容
full_response += content # 将内容追加到完整响应中
if chunk.choices[0].finish_reason == 'stop': # 检查响应结束原因
# 生成语音合成的音频
output = sambert_hifigan_tts(input=full_response, voice='zhitian_emo')
wav = output[OutputKeys.OUTPUT_WAV]
# 使用当前时间戳生成唯一的文件名
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}.wav"
file_path = os.path.join(directory_path, filename)
# 将音频保存到文件
with open(file_path, 'wb') as f:
f.write(wav)
# 生成嵌入网页的音频播放元素
audio_content = f"\n<audio src=\"{resolve_assets(filename)}\"></audio>"
# 更新历史记录中的助手响应包含音频
history[-1]['content'] = full_response + audio_content
yield '', history, messages_to_chatbot(history, True)
else:
# 实时更新助手的响应内容
history[-1]['content'] = full_response
yield '', history, messages_to_chatbot(history)
except Exception as e:
print(e) # 打印异常信息以进行调试
# 配置当用户提交输入时,调用 `chat` 函数,更新历史和聊天界面
input.submit(fn=chat, inputs=[input, history], outputs=[input, history, chatbot])
# 启动 Gradio 应用,设置服务器端口为 7860
app.launch(server_port=7860)
将编写的Gradio应用发布到创空间
在魔搭网站上点击创建创空间:
填写好名称和描述,使用gradio SDK类型创建创空间:
关联云资源:创空间内可以直接选择免费CPU资源。同时,Modelscope平台也提供了免费GPU资源供申请,若您的代码需要GPU运行环境,可以参考文档《xGPU创空间介绍》https://modelscope.cn/docs/studios/xGPU申请GPU资源。
创建完成后,在git仓库中创建新文件:
创建app.py,内容与notebook中相同:
创建requirements.txt,内容如下:
openai
modelscope_studio
填写环境变量,填入SDK token:
上线创空间,即可将应用分享给他人使用:
带有语音的聊天机器人4、构建一个文生图Gradio应用
我们先验证一下文生图模型的效果。以下代码请用Notebook GPU实例运行,否则耗时较长。
# 导入必要的库
from modelscope.utils.constant import Tasks
from modelscope.pipelines import pipeline
import cv2
from matplotlib import pyplot as plt
# 创建一个文本到图像合成的管道
pipe = pipeline(
task=Tasks.text_to_image_synthesis, # 指定任务类型
model='AI-ModelScope/stable-diffusion-v1-5', # 指定使用的模型
model_revision='v1.0.0' # 指定模型版本
)
# 定义用于图像生成的文本提示
prompt = '飞流直下三千尺,油画'
# 使用给定的提示通过管道生成输出
output = pipe({'text': prompt})
# 将生成的图像保存到文件
cv2.imwrite('result.png', output['output_imgs'][0])
# 使用matplotlib显示生成的图像
img = cv2.cvtColor(output['output_imgs'][0], cv2.COLOR_BGR2RGB) # 将BGR格式转换为RGB格式
plt.imshow(img) # 显示图片
plt.axis('off') # 关闭坐标轴标签
plt.title('生成的图像') # 设置图片的标题
plt.show() # 展示图片
我们可以将其增加Gradio的页面,开发为一个应用。
若要将此应用部署到Modelscope创空间内,您可以查阅文档( https://www.modelscope.cn/brand/view/xGPU )获取免费的GPU资源。
# 导入必要的库
import gradio as gr
import cv2
from modelscope.utils.constant import Tasks
from modelscope.pipelines import pipeline
import numpy as np
import random
import torch
# 仅在 Notebook 中使用需要以下代码,如果之前已经定义过 `app`,关闭它
try:
app.close()
except NameError:
# 如果 `app` 不存在,忽略这个异常
pass
# 设备检查
device = "cuda" if torch.cuda.is_available() else "cpu"
# 创建一个文本到图像合成的管道
pipe = pipeline(
task=Tasks.text_to_image_synthesis,
model='AI-ModelScope/stable-diffusion-v1-5',
model_revision='v1.0.0'
)
# 设置随机种子上限
MAX_SEED = np.iinfo(np.int32).max
# 定义图像生成的函数
def infer(prompt, seed=42, randomize_seed=False):
if randomize_seed:
seed = random.randint(0, MAX_SEED)
generator = torch.Generator(device).manual_seed(seed)
# 通过管道生成图像
output = pipe({'text': prompt, 'generator': generator})
img = output['output_imgs'][0]
return img, seed
# 示例中的提示
examples = [
"飞流直下三千尺,油画",
]
# 构建Gradio应用接口
with gr.Blocks() as demo:
gr.Markdown("### 文生图生成应用")
# 输入文本提示
prompt = gr.Textbox(
label="提示词",
placeholder="输入你的提示词",
)
# 创建运行按钮
run_button = gr.Button("生成图像")
# 输出生成的图像
result = gr.Image(label="生成的图像")
# 可选设置:随机种子
randomize_seed = gr.Checkbox(label="使用随机种子", value=False)
# 设定的seeds
seed = gr.Number(label="种子", value=42)
# 添加示例
gr.Examples(examples=examples, inputs=[prompt], outputs=[result, seed], fn=infer)
# 设置按钮动作
run_button.click(
infer,
inputs=[prompt, seed, randomize_seed],
outputs=[result, seed],
)
# 启动应用
if __name__ == "__main__":
demo.launch()
发布为xGPU创空间
关联云资源:创空间内可以直接选择免费CPU资源。同时,Modelscope平台也提供了免费GPU资源供申请,若您的代码需要GPU运行环境,可以参考文档《xGPU创空间介绍》https://modelscope.cn/docs/studios/xGPU申请GPU资源。
与前文部署方式相似,在申请完成免费GPU资源后,即可选择xGPU部署创空间。
预设课程大纲如下
✔️课程一:全栈产品经理启发课:AI加持后,从想法到落地,就是这么简单!
✔️课程二:Gradio组件学习:应用UI界面可无限DIY
✔️课程三:AI模型部署与推理:应用功能可无限拓展
✔️课程四:前后端联调及应用发布:打通前后端的任督二脉,就是完整的AI应用!(本次内容)
✔️课程五:案例学习:通过AI应用案例来实践,用微调的思路先做出你自己的第一个AI应用!
无论是对课程内容的疑问、对教学方式的建议,还是对未来课程主题的期待,都请不吝赐教。你可以通过公众号留言或是直接加入我们学习群的方式,分享你的想法。
课程学习群:
我们会从公众号留言中选取有用的建议来赠送魔搭周边小礼品哦!