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.

490 lines
22 KiB

1 month ago
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,
style={'width': "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-format',
size='large',
placeholder='选择模型格式',
options=model_formats_list,
style={'width': "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-size',
size='large',
placeholder='选择模型参数',
options=model_sizes_list,
style={'width': "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-quant',
size='large',
placeholder='选择量化参数',
options=model_quantizations_list,
style={'width': "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-model-gpu',
size='large',
placeholder='选择GPU或者CPU',
options=['auto', "cpu", "gpu"],
style={'width': 620},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-model-num',
size='large',
placeholder='填写部署模型数量',
style={
"width": "calc(100% - 30px)",
},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
],
),
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)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-worker-ip',
size='large',
placeholder='模型运行worker的地址',
style={"width": "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-gpu-idx',
size='large',
placeholder='模型运行GPU的索引',
style={"width": "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdSelect(
id='form-item-download-hub',
size='large',
placeholder='模型下载的地址',
options=['none', "huggingface", "modelscope", "modelscope"],
style={"width": "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
fac.AntdFormItem(
fac.AntdInput(
id='form-item-model-path',
size='large',
placeholder='模型本地运行的路径',
style={"width": "calc(100% - 30px)"},
),
labelCol={'flex': 'none'},
wrapperCol={'flex': 'auto'},
),
],
layout='vertical',
)
}
],
ghost=True,
),
fac.AntdButton(
'部署',
id='button-auto-spin-demo',
loadingChildren='部署中',
autoSpin=True,
type='primary',
style={
"marginTop": "10px",
"marginLeft": "10px"
}
),
]),
dash.ctx.triggered_id["model_name"]
]
@app.callback(
Output('button-auto-spin-demo', 'loading'),
Input('button-auto-spin-demo', 'nClicks'),
prevent_initial_call=True,
)
def button_auto_spin_demo(nClicks):
# 模拟计算任务耗时
time.sleep(2)
return False
#提交后执行外部访问
@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]
)