Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions __tests__/e2e/ci-mac-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,18 @@ fi
echo "test model download"
cd model
pip install -r requirements.txt
export fc_component_function_name=model-$(uname)-$(uname -m)-$RANDSTR
python deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoin-general_damo --region cn-shanghai --auto-cleanup
python deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --auto-cleanup
python deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoin-general_damo --region cn-shanghai --storage oss --auto-cleanup
python deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --storage oss --auto-cleanup
export fc_component_function_name=model-$(uname)-$(uname -m)-$RANDSTR-$RANDOM
python -u deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoin-general_damo --region cn-shanghai --auto-cleanup
python -u deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --auto-cleanup
python -u deploy_and_test_model.py --model-id iic/cv_LightweightEdge_ocr-recognitoin-general_damo --region cn-shanghai --storage oss --auto-cleanup
python -u deploy_and_test_model.py --model-id Qwen/Qwen2.5-0.5B-Instruct --region cn-shanghai --storage oss --auto-cleanup

echo "test model s_file.yaml"
# python -u test.py
s model download -t s_file.yaml
s deploy -y -t s_file.yaml
s model remove -t s_file.yaml
s remove -y -t s_file.yaml
cd ..

echo "test go runtime"
Expand Down
30 changes: 18 additions & 12 deletions __tests__/e2e/model/deploy_and_test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ def deploy_model(model_id: str, region: str = "cn-hangzhou", storage: str = "nas
tuple: (部署的URL, 配置文件路径)
"""
# 生成函数名称
function_name = f"test-{simple_hash(model_id)}"
# 加个随机数
function_name = f"test-{simple_hash(model_id)}-{secrets.token_hex(4)}"

# 准备请求数据
deploy_data = {
Expand Down Expand Up @@ -177,17 +178,6 @@ def test_model(model_id: str, deploy_url: str, s_yaml_file: str = None):
model_detail_url = f"{deploy_url}/model/info"
print(f"正在获取部署后的模型服务详情: {model_detail_url}")

try:
detail_response = requests.get(
model_detail_url, headers={"Authorization": f"Bearer {token}"}
)
if detail_response.status_code == 200:
print(f"部署后的模型服务详情: {detail_response.text}")
else:
print(f"获取部署后的模型服务详情失败: {detail_response.status_code}")
except Exception as e:
print(f"获取部署后的模型服务详情时出错: {e}")

# 检查是否是vLLM模型(通过配置文件中的启动命令)
is_vllm_model = False
if s_yaml_file:
Expand All @@ -212,6 +202,22 @@ def test_model(model_id: str, deploy_url: str, s_yaml_file: str = None):
print("检测到vLLM模型,将使用专用测试方法")
except Exception as e:
print(f"检查模型类型时出错: {e}")

# 先调用模型详情接口
model_detail_url = f"{deploy_url}/model/info"
if is_vllm_model:
model_detail_url = f"{deploy_url}/v1/models"
print(f"正在获取部署后的模型服务详情: {model_detail_url}")
try:
detail_response = requests.get(
model_detail_url, headers={"Authorization": f"Bearer {token}"}
)
if detail_response.status_code == 200:
print(f"部署后的模型服务详情: {detail_response.text}")
else:
print(f"获取部署后的模型服务详情失败: {detail_response.status_code}")
except Exception as e:
print(f"获取部署后的模型服务详情时出错: {e}")

if is_vllm_model:
# 对于vLLM模型,使用专门的测试方法
Expand Down
75 changes: 75 additions & 0 deletions __tests__/e2e/model/s_file.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
edition: 3.0.0
name: ai-model-app
access: quanxi

vars:
region: 'cn-hangzhou'

resources:
fc3:
component: ${env('fc_component_version', path('../../../'))}
type: Function
props:
logConfig: auto
functionName: fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
instanceLifecycleConfig:
preStop:
handler: 'true'
timeout: 300
gpuConfig:
gpuMemorySize: 16384
gpuType: fc.gpu.tesla.1
nasConfig: auto
runtime: custom-container
description: test model download files
cpu: 8
customContainerConfig:
image: >-
cap-demo-public-registry.cn-hangzhou.cr.aliyuncs.com/cap-app/image-generation-comfyui-agent:v1.1.0-beta.0
port: 9000
triggers:
- triggerConfig:
methods:
- GET
- POST
- PUT
- PATCH
- DELETE
- HEAD
authType: anonymous
disableURLInternet: false
triggerName: fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
qualifier: LATEST
description: http trigger for fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
triggerType: http
version: 1.6.0
timeout: 3600
instanceConcurrency: 200
diskSize: 61440
memorySize: 32768
internetAccess: true
environmentVariables:
BACKEND_TYPE: comfyui
MODEL_ASSET_DIR: /mnt/fc3-model-files-${env('fc_component_function_name', 'nodejs18')}
REGION: ${vars.region}
vpcConfig: auto
region: ${vars.region}
annotations:
modelConfig:
solution: funArt
source:
uri: 'oss://dipper-cache-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com'
downloadStrategy:
mode: once
target:
uri: 'nas://auto'
files:
- source:
path: base/comfyui/v0.3.59-alpha
target:
path: ''
- source:
path: >-
function-art/comfyui/models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors
target:
path: models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors
109 changes: 109 additions & 0 deletions __tests__/e2e/model/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3
import os
import subprocess
import time
import sys

def run_command_with_retry(cmd, silent=False, max_retries=3, timeout=300):
"""执行命令并返回结果,支持重试"""
for i in range(max_retries):
if not silent:
print(f"执行命令: {cmd} (尝试 {i+1}/{max_retries})")

try:
output = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, text=True, timeout=timeout)
return 0, output, ""
except subprocess.TimeoutExpired:
print(f"命令超时: {cmd}")
if i == max_retries - 1:
return -1, "", "Command timed out after retries"
except Exception as e:
print(f"命令执行出错: {str(e)}")
if i == max_retries - 1:
return -1, "", str(e)

return -1, "", "Failed after retries"

def main():
# 获取函数名(与YAML中一致)
fc_component_function_name = os.environ.get('fc_component_function_name', 'nodejs18')
function_name = f"fc3-model-files-{fc_component_function_name}"

print("开始执行模型部署和实例检查流程...")
print(f"函数名: {function_name}")

# 1. 执行模型下载
print("1. 执行模型下载: s model download -t s_file.yaml")
subprocess.check_output(f"s model download -t s_file.yaml",shell=True)

# 2. 部署模型
print("2. 执行部署: s deploy -y -t s_file.yaml")
subprocess.check_output(f"s deploy -y -t s_file.yaml --skip-push",shell=True)

# 3. 调用函数确保实例启动
print("3. 调用函数确保实例启动: s invoke -t s_file.yaml")
subprocess.check_output(f"s invoke -t s_file.yaml",shell=True)

# 4. 等待实例启动
print("4. 等待实例启动...")
time.sleep(10)

# 5. 获取实例列表并提取instanceId
print("5. 获取实例列表: s instance list -t s_file.yaml")
ret_code, instance_output, stderr = run_command_with_retry("s instance list -t s_file.yaml")

if ret_code == 0:
print("实例列表:")
print(instance_output)

# 提取第一个instanceId
instance_id = None
for line in instance_output.split('\n'):
if 'instanceId:' in line:
instance_id = line.split('instanceId:')[1].strip()
break

if instance_id:
print(f"提取到的instanceId: {instance_id}")

# 6. 执行详细检查
cmd = f"s instance exec --instance-id {instance_id} --cmd 'ls /mnt/{function_name}/models/checkpoints/v1-5-pruned-emaonly-fp16.safetensors'"
print(f"6. 执行详细检查: {cmd}")
ret_code, find_output, stderr = run_command_with_retry(cmd)
print(f"文件查找结果: {find_output}, 错误信息: {stderr}, 状态码: {ret_code}")

if ret_code == 0:
print("文件查找结果:")
print(find_output)

if "v1-5-pruned-emaonly-fp16.safetensors" in find_output:
print("✓ 文件存在路径确认")
else:
print("✗ 文件未在/mnt/auto目录下找到")
# 文件不存在,终止流程
sys.exit(1)
else:
print("文件查找命令执行失败:")
print(find_output)
print(f"错误信息: {stderr}")
# 命令执行失败,终止流程
sys.exit(1)
else:
print("✗ 未找到instanceId")
else:
print("✗ 获取实例列表失败:")
print(instance_output)
print(f"错误信息: {stderr}")

# 7. 执行模型移除
print("7. 执行模型移除: s model remove -t s_file.yaml")
subprocess.check_output(f"s model remove -t s_file.yaml", shell=True)

# 8. 移除部署
print("8. 移除部署: s remove -y -t s_file.yaml")
subprocess.check_output(f"s remove -y -t s_file.yaml", shell=True)

print("测试流程完成")

if __name__ == "__main__":
main()
Loading