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.
 
 

488 lines
22 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,launch_model_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=False,
)
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'},
),
],
id='form-model-basic-value',
enableBatchControl=True,
),
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"],
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',
id='form-model-option-value',
enableBatchControl=True,
)
}
],
ghost=True,
# id='form-model-option-value',
# enableBatchControl=True,
),
fac.AntdButton(
'部署',
id='button-deploy',
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)
# launch_model_api()
# return False
@app.callback(
Output('button-deploy', 'loading'),
Input('button-deploy', 'nClicks'),
[
State('form-model-basic-value', 'values'),
State('form-model-option-value', 'values'),
State('side-drawer', 'title')
],
prevent_initial_call=True,
)
def callback_listen_value_demo(nClicks,basic_values,option_values,model_name):
print("进入部署回调",basic_values,option_values)
# time.sleep(2)
merged_data = {**(basic_values or {}), **(option_values or {})}
# merged_values = {**basic_values, **option_values}
params = {
"model_engine": merged_data.get('form-item-model-engine'),
"model_uid": merged_data.get('form-item-model-id'),
"model_name": model_name, # This value is hardcoded as per your request
"model_format": merged_data.get('form-item-model-format'),
"model_size_in_billions": merged_data.get('form-item-model-size')
}
print("请求部署的参数",params)
re = launch_model_api(params)
print(re)
return False
@app.callback(
Output('tabs-demo-output', 'children'), Input('tabs-demo', 'activeKey')
)
def tabs_demo(activeKey):
return f'activeKey: {activeKey}'
@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]
)