You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

521 lines
25 KiB

import dash
import time
import uuid
from dash import dcc,html
from dash.dependencies import Input, Output, State, ALL
from dash.exceptions import PreventUpdate
import feffery_utils_components as fuc
import feffery_antd_components as fac
import feffery_markdown_components as fmc
from server import app
from utils.common import validate_data_not_empty,process_string
from api.modmag import get_model_info_api,get_model_info_extend_api,get_model_engine_api
app.clientside_callback(
'''(value) => value''',
Output('model-tree', 'searchKeyword'),
Input('model-input-search', 'value')
)
@app.callback(
[Output("side-drawer", "visible"), Output("side-drawer", "children"),Output('side-drawer', 'title')],
Input(
{
"type": "card-button",
"model_name": ALL,
"index": ALL,
},
"nClicks",
),
State('model-infos', 'data'),
prevent_initial_call=True,
)
# def control_side_drawer(_,model_infos):
# return [
# True,
# "产品 {} 的 {} 被点击了".format(
# dash.ctx.triggered_id["model_name"], dash.ctx.triggered_id["index"]
# ),
# ]
def control_side_drawer(_,model_infos):
print("进入回调")
# print(dash.ctx.triggered_id["model_name"])
# print("********")
# print(model_infos)
# print("********")
# mode_info = get_model_info_api(dash.ctx.triggered_id["model_name"])
# print(model_infos)
# mode_info_extend = get_model_info_extend_api(dash.ctx.triggered_id["model_name"])
if dash.ctx.triggered_id["index"] == "button1":
mode_info = get_model_info_api(dash.ctx.triggered_id["model_name"])
return [
True,
[
fac.AntdDescriptions(
[
fac.AntdDescriptionItem(mode_info["model_name_en"], label='英文名称'),
fac.AntdDescriptionItem(mode_info["model_name_cn"], label='中文名称'),
fac.AntdDescriptionItem(mode_info["model_fune_flag"], label='微调支持'),
fac.AntdDescriptionItem(mode_info["model_release_date"], label='发布日期'),
fac.AntdDescriptionItem(
html.A(
mode_info["model_website_url"],
href= mode_info["model_website_url"],
),
label='模型网址',
span=2
),
fac.AntdDescriptionItem(
mode_info["model_note"],
label='模型描述',
span=2
),
fac.AntdDescriptionItem(
mode_info["model_prmopt"],
label='prompt示例',
span=2
),
],
# title='描述列表示例',
# bordered=True,
column=2,
# layout='vertical',
labelStyle={'fontWeight': 'bold',
'fontSize': '16px',
},
contentStyle={
'fontSize': '16px',
},
)
],dash.ctx.triggered_id["model_name"]
]
elif dash.ctx.triggered_id["index"] == "button2":
mode_info_extend = get_model_info_extend_api(dash.ctx.triggered_id["model_name"])
return [
True,
fac.AntdTabs(
items=[
{
'key': f'curl',
'label': f'curl',
'children': fmc.FefferySyntaxHighlighter(
codeString= mode_info_extend["curl_code"],
language='sql',
codeTheme='night-owl',
# ),
codeStyle={
# 'backgroundColor': 'rgb(240, 242, 245)',
'maxHeight': '100px', # 确保代码块高度不超过右侧区域的50%
'overflowY': 'scroll',
'overflowX': 'scroll',
'fontSize': '16px'
# 'paddingLeft': '5px',
# 'marginTop': '5px'
}
),
},
{
'key': f'python',
'label': f'python',
'children': fmc.FefferySyntaxHighlighter(
codeString= mode_info_extend["python_code"],
language='python',
codeTheme='night-owl',
# ),
codeStyle={
# 'backgroundColor': 'rgb(240, 242, 245)',
'maxHeight': '400px', # 确保代码块高度不超过右侧区域的50%
'overflowY': 'scroll',
'overflowX': 'scroll',
'fontSize': '16px'
# 'paddingLeft': '5px',
# 'marginTop': '5px'
}
),
},
{
'key': f'java',
'label': f'java',
'children': fmc.FefferySyntaxHighlighter(
codeString= mode_info_extend["java_code"],
language='java',
codeTheme='night-owl',
# ),
codeStyle={
# 'backgroundColor': 'rgb(240, 242, 245)',
'maxHeight': '400px', # 确保代码块高度不超过右侧区域的50%
'overflowY': 'scroll',
'overflowX': 'scroll',
'fontSize': '16px'
# 'paddingLeft': '5px',
# 'marginTop': '5px'
}
),
}
],
style={'fontSize': 40},
size = 'large'
),
dash.ctx.triggered_id["model_name"]
]
elif dash.ctx.triggered_id["index"] == "button3":
mode_engine_info = get_model_engine_api(dash.ctx.triggered_id["model_name"])
print(mode_engine_info)
print(type(mode_engine_info))
model_engines = list(mode_engine_info.keys())
# 用于存储所有model_format的列表
model_formats = set()
model_sizes = set()
model_quantizations = set()
# 遍历每个分类
for item in mode_engine_info.values():
for model in item:
model_formats.add(model['model_format'])
model_sizes.add(model['model_size_in_billions'])
for quant in model['quantizations']:
model_quantizations.add(quant)
# 将集合转换为列表
model_formats_list = list(model_formats)
model_sizes_list = list(model_sizes)
model_quantizations_list = list(model_quantizations)
return [
True,
html.Div([
# fac.AntdDivider('基础信息', innerTextOrientation='left'),
fac.AntdForm(
[
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-engine',
size='large',
placeholder='选择模型引擎',
options= model_engines,
# value='选项1',
style={'width': 620},
),
# label='模型引擎',
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-format',
size='large',
placeholder='选择模型格式',
options= model_formats_list,
# value='选项1',
style={'width': 620},
),
# label='模型引擎',
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-size',
size='large',
placeholder='选择模型参数',
options= model_sizes_list,
# value='选项1',
style={'width': 620},
),
# label='模型引擎',
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-quant',
size='large',
placeholder='选择量化参数',
options= model_quantizations_list,
# value='选项1',
style={'width': 620},
),
# label='模型引擎',
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-gpu',
size='large',
placeholder='选择GPU或者CPU',
options= ['auto',"cpu","gpu"],
# value='选项1',
style={'width': 620},
),
# label='模型引擎',
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-model-num',
size='large',
placeholder='填写部署模型数量',
style={
# "position": "absolute",
# "bottom": 8,
# "right": 20,
"width": "calc(100% - 30px)",
},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdAccordion(
items=[
{
'title': f'补充信息',
'key': f'补充信息',
'children': fac.AntdForm(
[
fac.AntdFormItem(
fac.AntdInput(
id='form-item-model-id',
size='large',
placeholder='设置运行模型名称',
style={
"width": "calc(100% - 30px)",
},
),
# id='form-item-validate-demo-username-container',
# label='用户名',
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-worker-ip',
size='large',
placeholder='设置运行模型的worker地址',
style={
"width": "calc(100% - 30px)",
"marginTop": "5px"
},
),
style={
"marginTop": "5px"}
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-gpu-idx',
size='large',
placeholder='设置运行模型的gpu索引',
style={
"width": "calc(100% - 30px)",
"marginTop": "5px"
},
),
style={
"marginTop": "5px"}
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-download-hub',
size='large',
placeholder='选择下载地址',
options= ['none',"huggingface","modelscope","modelscope"],
# value='选项1',
style={'width': 620,
"marginTop": "5px"
},
),
style={
"marginTop": "5px"}
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-model-path',
size='large',
placeholder='指定模型路径启动',
style={
"width": "calc(100% - 30px)",
"marginTop": "5px"
},
),
style={
"marginTop": "5px"}
),
],
layout='vertical',
)
}
],
ghost=True,
style={
"height": 300}
),
),
fac.AntdFormItem(
fac.AntdButton(
'部署',
id='form-item-model-demo-submit',
type='primary',
)
),
],
# style={'width': 300},
)
]),
dash.ctx.triggered_id["model_name"]
]
# app.clientside_callback(
# # 处理控件组编辑抽屉的打开
# "() => true",
# Output({"type": "side-drawer"}, "visible"),
# Input(
# {
# "type": "card-button",
# "model_name": ALL,
# "index": ALL,
# },
# "nClicks",
# ),
# prevent_initial_call=True,
# )
#提交后执行外部访问
@app.callback(
[
Output('form-item-validate-demo-username-container', 'validateStatus'),
Output('form-item-validate-demo-password-container', 'validateStatus'),
Output('form-item-validate-demo-username-container', 'help'),
Output('form-item-validate-demo-password-container', 'help'),
],
Input('form-item-validate-demo-submit', 'nClicks'),
[
State('form-item-validate-demo-username', 'value'),
State('form-item-validate-demo-password', 'value'),
],
prevent_initial_call=True,
)
def form_item_model_process(nClicks, username, password):
if username and password:
return [
None if username == 'fac' else 'error',
('success' if password == '123456' else 'error')
if username == 'fac'
else None,
None if username == 'fac' else '用户不存在!',
('密码正确!' if password == '123456' else '密码错误!')
if username == 'fac'
else None,
]
return [
None if username else 'error',
None if password else 'error',
None if username else '用户名不能为空!',
None if password else '密码不能为空!',
]
@app.callback(
Output('card-container', 'children'),
[
Input('model-tree', 'selectedKeys'),
Input('model-search', 'nClicks'),
],
[
State('model-name-input', 'value'),
State('model-ability-select', 'value'),
State('model-status-select', 'value'),
State('model-infos', 'data')
],
prevent_initial_call=True,
)
# prevent_initial_call=True,
def get_model_data_by_tree(selectedKeys, search_click,
model_name, model_ability, model_status,model_infos):
print("进入选择回调new")
# print(selectedKeys)
# print(model_infos)
model_type = selectedKeys[0].split('/')[0]
model_family = selectedKeys[0].split('/')[1]
# 筛选出符合条件的项
data_new = [
item for item in model_infos
if item["model_type"] == model_type and item["model_family"] == model_family
]
return fac.AntdRow(
[
fac.AntdCol(
fac.AntdCard(
title=item.get('model_name'),
children=[
fac.AntdSpace(
[
html.Div(
fac.AntdCompact([
fac.AntdTag(content=tag)
for tag in (
(item['model_flag'].get('model_lang') if isinstance(item['model_flag'].get('model_lang'), list) else [item['model_flag'].get('model_lang')]) +
(item['model_flag'].get('model_ability') if isinstance(item['model_flag'].get('model_ability'), list) else [item['model_flag'].get('model_ability')]) +
([str(item['model_flag'].get('context_length'))] if item['model_flag'].get('context_length') is not None else [])
)
if tag is not None
])
),
html.Div(
process_string(item['model_description']),
# style={"marginBottom": "5px"}
),
html.Div(
fac.AntdCompact(
[
fac.AntdButton('查询信息',
id={
"type": "card-button",
"model_name": item['model_name'],
"index": "button1",
},
style={'backgroundColor': '#f0f0f0', 'border': 'none', 'marginRight': '1px'}
),
fac.AntdButton('接口示例',
id={
"type": "card-button",
"model_name": item['model_name'],
"index": "button2",
},
style={'backgroundColor': '#f0f0f0', 'border': 'none', 'marginRight': '1px'}
),
fac.AntdButton('部署模型',
id={
"type": "card-button",
"model_name": item['model_name'],
"index": "button3",
},
style={'backgroundColor': '#f0f0f0', 'border': 'none'}
),
]
)
),
],
align='start',
direction='vertical',
),
],
hoverable=True,
style={"marginBottom": "5px", "width": "100%", "height": "210px"},
headStyle={"width": "100%"},
),
span=8,
style={
"width": "100%",
# "marginTop": "-1px"
},
)
for item in data_new
],
gutter=[25, 25]
)