应用链接: https://979427749bc9ceec34.gradio.live 是公开访问链接,3天有效。在modelscope中的创空间怎么长期发布我还在研究。后面补上。
应用图如下,源代码见正文。
知道Gradio
AI大模型快速生成应用的工具,
在Huggingface 的Space空间方式有Gradio和Streamlit:
在国内的AI模型开源社区 ModelScope 的创空间 有Gradio和Streamlit。
他们都可以搭建一个快速的应用,比如Gradio搭的ChatGPT式的问答(这半年多特别流程的大模型应用):
图:modelscope创空间的通义千问 Chat Bot (2023年08月10日)
然后搜了些材料,发现
Gradio | Streamlit | |
---|---|---|
网址 | https://www.gradio.app | https://streamlit.io |
上手难度 | 简单 | 简单,比左边难一点,因为丰富 |
组件丰富度 | 低 | 高 |
扩展性 | 低 | 中 |
Jupyter Notebook 内支持 | 是 | 否 |
Streamlit可以支持封装自己的前端组件组合用。 不过看小白们都爱Gradio,作为码代码少的人士,喜欢Notebook,我选择了Gradio去做demo。
了解Gradio
了解一个开发者软件怎么用,最快速的就是翻它的文档,别人写的容易有偏。
官方例子跑一跑,然后看几个别人的代码跑一跑,然后自己编一个需求跑一跑。
官方文档:https://www.gradio.app/guides/quickstart 的截图如下
运行环境
运行环境:在国内各大开发者平台的厂商都提供了”薅羊毛“的机会,比如在ModelScope就链接了阿里云的PAI-DSW,会有一个Jupyter Notebook环境。 薅它,香:
打开后是这样的Notebook,可以搞自己的开发,还可以git与创空间的git仓库连上:
(这个图内是我编的文件,后文分享)
一个鸡兔同笼的例子,用了达摩院的MindOpt优化求解器
运行之前,先安装两个库,gradio和mindoptpy,在Jupyter的Terminal里面运行。
安装达摩院的MindOpt优化求解器是用来解方程,也可以去他们的官网捞复杂案例来学习:https://opt.aliyun.com/#/platform/case
pip install gradio
pip install mindoptpy
然后建立一个 .ipynb的文件,选择Python 3内核。
然后运行如下程序后,设置最后一行生成公开访问连接后,会得到:
Running on local URL: http://127.0.0.1:7932
Running on public URL: https://979427749bc9ceec34.gradio.live
This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)
其中,https://979427749bc9ceec34.gradio.live 是公开访问链接,3天有效。需要部署后才能长期有效。 modelscope的创空间发布后也能长期有效,我还在研究怎么发布。
电脑端打开是根据我的浏览器的主题来的,这样的:
完整代码
import gradio as gr
from mindoptpy import *
def solverCalc(touNum0 = 35, zuNum0 = 94):
touNum = int(touNum0)
zuNum = int(zuNum0)
MDO_INFINITY = MdoModel.get_infinity()
tuziNum = -1
jiNum = -1
# 声明参数
# Step 1. Create a model and change the parameters.
model = MdoModel()
try:
# Add variables.
var = {}
var["tuziNum"] = model.add_var(0, MDO_INFINITY, 0, None, "tuziNum", True)
var["jiNum"] = model.add_var(0, MDO_INFINITY, 0, None, "jiNum", True)
# Add constraints.
# 头的数目
cons = {}
cons["touNum"] = model.add_cons(touNum, touNum, var["tuziNum"] + var["jiNum"], "touNum")
cons["zuNum"] = model.add_cons(zuNum, zuNum, 4 * var["tuziNum"] + 2 * var["jiNum"], "touNum")
# Step 3. Solve the problem and populate the result.
model.solve_prob()
model.display_results()
time.sleep(1) #for print
status_code, status_msg = model.get_status()
if status_msg == "OPTIMAL":
tuziNum = int(var["tuziNum"].get_real_attr("PrimalSoln"))
jiNum = int(var["jiNum"].get_real_attr("PrimalSoln"))
if 0:
print("----\n")
print("The solver terminated with an OPTIMAL status (code {0}).".format(status_code))
print("原始解是:")
for var_name,var_val in var.items():
primal_soln = var_val.get_real_attr("PrimalSoln")
print(var_name," : " ,primal_soln)
print("对偶解是:")
for cons_name,cons_val in cons.items():
dual_soln = cons_val.get_real_attr("DualSoln")
print(cons_name," : " ,dual_soln)
else:
#print("Optimizer terminated with a(n) {0} status (code {1}).".format(status_msg, status_code))
tuziNum = "输入问题错误"
jiNum = "输入问题错误"
except MdoError as e:
print("Received Mindopt exception.")
print(" - Code : {}".format(e.code))
print(" - Reason : {}".format(e.message))
except Exception as e:
print("Received exception.")
print(" - Reason : {}".format(e))
finally:
# Step 4. Free the model.
model.free_mdl()
return [tuziNum,jiNum]
def puzzleGen(tuziNum0,jiNum0):
tuziNum = int(tuziNum0)
jiNum = int(jiNum0)
touNum = tuziNum + jiNum
zuNUm = 4*tuziNum + 2* jiNum
return [touNum, zuNUm]
with gr.Blocks() as run:
gr.Markdown("# 用阿里达摩院MindOpt来做小应用")
# 第1个功能
gr.Markdown("\n---\n")
gr.Markdown("## 鸡兔同笼问题**计算器**")
gr.Markdown("请修改【头】和【脚】和的数量:")
with gr.Row():
inp = [gr.Textbox(label="上有多少头?如35"),
gr.Textbox(label="下有多少脚?如94")]
gr.Markdown("MindOpt计算结果:")
with gr.Row():
out = [gr.Textbox(label="兔子数量"),gr.Textbox(label="鸡数量")]
btn = gr.Button(value="计算",variant='primary')
btn.click(fn=solverCalc, inputs=inp, outputs=out)
# 第二个功能
gr.Markdown("## 鸡兔同笼问题**生成器**")
gr.Markdown("请修改【兔】和【鸡】和的数量:")
with gr.Row():
inp2 = [gr.Textbox(label="兔子多少只?如12"),
gr.Textbox(label="鸡有多少只?如23")]
gr.Markdown("生成问题:")
with gr.Row():
out2 = [gr.Textbox(label="头数量"),gr.Textbox(label="脚数量")]
btn2 = gr.Button(value="生成问题",variant='primary')
btn2.click(fn=puzzleGen, inputs=inp2, outputs=out2)
run.launch()#share=True) # share=True的时候生成公开可访问的连接,3天有效,调试的时候注释掉就行。
代码分块讲解
功能函数:
def puzzleGen(tuziNum0,jiNum0):
def solverCalc(touNum0 = 35, zuNum0 = 94):
这是两个我做的功能,用来接收收到的信息,然后处理返回对应的信息。 这里注意计算的时候是数值,实际传过来的可能是字符,还没有搞清楚,有些gradio的参数设置了后,返回的内容会导致string无法转数字,计算不了。
其中puzzleGen()是鸡兔的头和脚的计算,很简单的计算逻辑
touNum = tuziNum + jiNum
zuNUm = 4*tuziNum + 2* jiNum
另一个solverCalc()是根据头和脚的计算鸡和兔。设置兔和鸡数量是整数变量 tuNum、jiNum,然后列一个简单的方程:
目标:0 #不设优化目标
约束: touNum = tuziNum + jiNum
zuNUm = 4tuziNum + 2 jiNum
然后根据MindOpt的Python库的用法mindoptpy来写程序。注意,有可能会有输入问题是错误的情况(求解器领域叫”不可解“),此时需要做异常处理。
Gradio 引用
下面是一个设置界面的参考,完整代码搞了两个,这里方便讲解:
with gr.Blocks() as run:
gr.Markdown("# 用阿里达摩院MindOpt来做小应用")
# 第1个功能
gr.Markdown("\n---\n")
gr.Markdown("## 鸡兔同笼问题**计算器**")
gr.Markdown("请修改【头】和【脚】和的数量:")
with gr.Row():
inp = [gr.Textbox(label="上有多少头?如35"),
gr.Textbox(label="下有多少脚?如94")]
gr.Markdown("MindOpt计算结果:")
with gr.Row():
out = [gr.Textbox(label="兔子数量"),gr.Textbox(label="鸡数量")]
btn = gr.Button(value="计算",variant='primary')
btn.click(fn=solverCalc, inputs=inp, outputs=out)
run.launch()#share=True) # share=True的时候生成公开可访问的连接,3天有效,调试的时候注释掉就行。
其中 gr.Blocks() 相当于一个块,把要的东西塞进去。 gradio有很多组件,可以运行 help(gr.components) 来查询用法。
- 这里前面是Markdown语法添加了些文字。
- gr.Row()是一行塞的东西,这里面塞了俩个text文字填写框。
- gr.Button() 是摁键组件。
- 然后.click是执行任务。
- 最后一个是run这个应用launch起来。注意里面也有参数设置,调试的时候本地调试就行。
然后根据Notebook的运行调试就有运行效果啦,可以在Notebook里面点点点测试,也可以用生成的浏览器链接打开测试。公开的链接,还可以在手机上打开:
比如:
1.正确的问题解答示例 | 2. 问题错误的示例: |
---|---|