diff --git a/example/s-pipeline.yaml b/example/s-pipeline.yaml new file mode 100644 index 00000000..c49ef2d9 --- /dev/null +++ b/example/s-pipeline.yaml @@ -0,0 +1,61 @@ +edition: 3.0.0 +name: ai-model-app +access: quanxi + +resources: + modelDemo: + component: fc3 + props: + region: cn-shanghai + runtime: custom-container + functionName: ${env('fc_component_function_name', 'ai-model-test-qwen-pipeline')} + description: model service from functionai test + logConfig: auto + vpcConfig: auto + nasConfig: auto + instanceConcurrency: 20 + cpu: 8 + memorySize: 65536 + diskSize: 10240 + timeout: 300 + gpuConfig: + gpuMemorySize: 49152 + gpuType: fc.gpu.ada.1 + customContainerConfig: + image: >- + serverless-registry.cn-hangzhou.cr.aliyuncs.com/functionai/modelscope:ubuntu22.04-cuda12.1.0-py311-torch2.3.1-tf2.16.1-1.26.0 + port: 9000 + entrypoint: + - sh + - '-c' + - >- + mkdir -p /.function_model && curl -fL --retry 3 -o + /.function_model/server.py + https://images.devsapp.cn/modelscope/server.py && MODEL_ID="${env('MODEL_ID', 'iic/SenseVoiceSmall')}" MODEL_VERSION="${env('MODEL_VERSION', 'master')}" MODEL_PATH="/mnt/${env('fc_component_function_name', 'ai-model-test-qwen-pipeline')} /${env('MODEL_ID', 'iic/SenseVoiceSmall')}" TASK="${env('TASK')}" python3 -u /.function_model/server.py + triggers: # 默认,用户可能关注的是开启 authType 是 bear token + - triggerConfig: + methods: + - GET + - POST + - PUT + - DELETE + authType: anonymous + disableURLInternet: false + triggerName: httpTrigger + description: '' + qualifier: LATEST + triggerType: http + provisionConfig: + target: 1 + alwaysAllocateCPU: false + alwaysAllocateGPU: false + mode: sync + + supplement: + modelConfig: + source: modelscope + id: ${env('MODEL_ID', 'iic/SenseVoiceSmall')} + # id: Qwen/Qwen3-14B + storage: nas + role: acs:ram::${config('AccountID')}:role/aliyundevsdefaultrole + diff --git a/example/s.yaml b/example/s.yaml index 129c0d6d..6b2c2f13 100644 --- a/example/s.yaml +++ b/example/s.yaml @@ -4,7 +4,7 @@ access: quanxi resources: modelDemo: - component: fc3@dev + component: fc3 props: region: cn-shanghai runtime: custom-container diff --git a/example/test_models.sh b/example/test_models_VLLM.sh similarity index 100% rename from example/test_models.sh rename to example/test_models_VLLM.sh diff --git a/example/test_models_pipeline.sh b/example/test_models_pipeline.sh new file mode 100755 index 00000000..2a83f6c5 --- /dev/null +++ b/example/test_models_pipeline.sh @@ -0,0 +1,120 @@ +#!/bin/bash + +# 定义日志文件 +LOG_FILE="test_models.log" + +# 清空或创建日志文件 +> "$LOG_FILE" + +# 日志记录函数 +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE" +} + +# 定义模型列表 (每个元素包含model_version, model_id, task) +MODEL_LIST=( + '{"model_version": "v2.4.0", "model_id": "iic/cv_convnextTiny_ocr-recognition-general_damo", "task": "ocr-recognition", "input":{"image":"http://modelscope.oss-cn-beijing.aliyuncs.com/demo/images/image_ocr_recognition.jpg"}' + '{"model_version": "master", "model_id": "iic/SenseVoiceSmall", "task": "auto-speech-recognition", "input": "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav"}' +) + +# 检查yaml文件是否存在 +YAML_FILE="s.yaml" +if [ ! -f "$YAML_FILE" ]; then + log "Error: $YAML_FILE not found!" + exit 1 +fi + +# 遍历每个model_id +for MODEL_INFO in "${MODEL_LIST[@]}"; do + log "========================================" + log "Testing model: $MODEL_INFO" + log "========================================" + # 从JSON对象中提取字段 (使用 jq) + export MODEL_VERSION=$(echo "$MODEL_INFO" | grep -o '"model_version": *"[^"]*' | awk -F'"' '{print $4}') + export MODEL_ID=$(echo "$MODEL_INFO" | grep -o '"model_id": *"[^"]*' | awk -F'"' '{print $4}') + export TASK=$(echo "$MODEL_INFO" | grep -o '"task": *"[^"]*' | awk -F'"' '{print $4}') + INPUT=$(echo "$MODEL_INFO" | grep -o '"input": *"[^"]*' | awk -F'"' '{print $4}') + + # 生成随机函数名 + RANDOM_STRING=$(openssl rand -hex 10) + export fc_component_function_name=ai-model-qwen-$RANDOM_STRING + export NEW_MODEL_SERVICE_CLIENT_CONNECT_TIMEOUT=10000 + + # 下载模型 + log "Downloading model..." + DOWNLOAD_OUTPUT=$(s model download -t s-pipeline.yaml 2>&1) + echo "$DOWNLOAD_OUTPUT" >> "$LOG_FILE" + echo "$DOWNLOAD_OUTPUT" + if echo "$DOWNLOAD_OUTPUT" | grep -q "Error"; then + log "Failed to download model: $MODEL_ID" + continue + fi + + # 部署服务 + log "Deploying..." + DEPLOY_OUTPUT=$(s deploy -t s-pipeline.yaml -y 2>&1) + echo "$DEPLOY_OUTPUT" >> "$LOG_FILE" + echo "$DEPLOY_OUTPUT" + + # 检查部署是否成功 + if echo "$DEPLOY_OUTPUT" | grep -q "state:.*Active"; then + log "Deployment successful for model: $MODEL_ID" + else + log "Deployment failed for model: $MODEL_ID" + # 清理资源 + REMOVE_OUTPUT=$(s model remove -t s-pipeline.yaml -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + REMOVE_OUTPUT=$(s remove -t s-pipeline.yaml -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + continue + fi + + # 提取system_url + SYSTEM_URL=$(echo "$DEPLOY_OUTPUT" | grep "system_url:" | sed 's/.*system_url: *//' | tr -d ' "[:cntrl:]') + if [ -z $SYSTEM_URL ]; then + log "Failed to extract system_url for model: $MODEL_ID" + # 清理资源 + REMOVE_OUTPUT=$(s model remove -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + REMOVE_OUTPUT=$(s remove -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + continue + fi + log "Extracted system_url: $SYSTEM_URL" + + # 发送测试请求 + log "Sending test request..." + CURL_OUTPUT=$(curl -v -d '{"input":$INPUT}' $SYSTEM_URL 2>&1) + + echo "$CURL_OUTPUT" >> "$LOG_FILE" + echo "$CURL_OUTPUT" + + # 检查curl请求是否成功 + if echo "$CURL_OUTPUT" | grep -q '"object":"chat.completion"'; then + log "Model test successful for: $MODEL_ID" + # 提取并显示模型回复内容 + RESPONSE_CONTENT=$(echo "$CURL_OUTPUT" | sed -n 's/.*"text":"\([^"]*\)".*/\1/p' | sed 's/\\n/\n/g' | sed 's/\\t/\t/g') + log "Model response: $RESPONSE_CONTENT" + else + log "Model test failed for: $MODEL_ID" + fi + + # 清理资源 + log "Removing resources..." + REMOVE_OUTPUT=$(s model remove -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + REMOVE_OUTPUT=$(s remove -y 2>&1) + echo "$REMOVE_OUTPUT" >> "$LOG_FILE" + echo "$REMOVE_OUTPUT" + + log "" + log "Finished testing model: $MODEL_ID" + log "" +done + +log "All models tested." \ No newline at end of file diff --git a/src/subCommands/deploy/impl/function.ts b/src/subCommands/deploy/impl/function.ts index 7d2d6333..9c3a3025 100644 --- a/src/subCommands/deploy/impl/function.ts +++ b/src/subCommands/deploy/impl/function.ts @@ -402,7 +402,7 @@ nasConfig: userId: 0 mountPoints: - serverAddr: ${mountTargetDomain}:/${functionName}${isEmpty(modelConfig) ? '' : '/' + modelConfig.id} - mountDir: /mnt/${functionName}${isEmpty(modelConfig) ? '' : '/' + modelConfig.id} + mountDir: /mnt/${functionName} enableTLS: false\n`), ); this.createResource.nas = { mountTargetDomain, fileSystemId }; @@ -412,7 +412,7 @@ nasConfig: mountPoints: [ { serverAddr: `${mountTargetDomain}:/${functionName}${isEmpty(modelConfig) ? '' : '/' + modelConfig.id}`, - mountDir: `/mnt/${functionName}${isEmpty(modelConfig) ? '' : '/' + modelConfig.id}`, + mountDir: `/mnt/${functionName}`, enableTLS: false, }, ], diff --git a/src/subCommands/model/index.ts b/src/subCommands/model/index.ts index d00bec45..1a7a863c 100644 --- a/src/subCommands/model/index.ts +++ b/src/subCommands/model/index.ts @@ -14,7 +14,7 @@ import assert from 'assert'; import { sleep } from '../../utils'; export const NEW_MODEL_SERVICE_CLIENT_CONNECT_TIMEOUT: number = - parseInt(process.env.NEW_MODEL_SERVICE_CLIENT_CONNECT_TIMEOUT as string, 10) || 5 * 1000; + parseInt(process.env.NEW_MODEL_SERVICE_CLIENT_CONNECT_TIMEOUT as string, 10) || 10 * 1000; export const NEW_MODEL_SERVICE_CLIENT_READ_TIMEOUT: number = parseInt(process.env.NEW_MODEL_SERVICE_CLIENT_READ_TIMEOUT as string, 10) || 86400 * 1000; export const MODEL_DOWNLOAD_TIMEOUT: number = @@ -111,7 +111,7 @@ groupId: 0 userId: 0 mountPoints: - serverAddr: ${mountTargetDomain}:/${functionName}/${supplement.modelConfig.id} - mountDir: /mnt/${functionName}/${supplement.modelConfig.id} + mountDir: /mnt/${functionName} enableTLS: false\n`), ); this.createResource.nas = { mountTargetDomain, fileSystemId }; @@ -121,7 +121,7 @@ mountPoints: mountPoints: [ { serverAddr: `${mountTargetDomain}:/${functionName}/${supplement.modelConfig.id}`, - mountDir: `/mnt/${functionName}/${supplement.modelConfig.id}`, + mountDir: `/mnt/${functionName}`, enableTLS: false, }, ],