You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SageMaker部署SpaCy模型端点时遇CannotStartContainerError错误求助

排查AWS SageMaker部署SpaCy模型端点失败的问题

问题根源分析

出现CannotStartContainerError的核心原因是容器不符合SageMaker推理容器规范,同时代码和配置存在多处错误:

  • 未实现SageMaker推理接口:SageMaker启动容器时会执行docker run <image> serve命令,要求容器启动HTTP服务监听8080端口,处理/ping(健康检查)和/invocations(推理请求)两个端点。当前配置直接运行脚本,未处理serve参数也未启动服务。
  • 模型路径错误:SageMaker会自动将S3中的model.tar.gz解压到容器内的/opt/ml/model目录,而代码中写的./model/modelo路径不匹配。
  • 依赖不匹配:Dockerfile中安装的是en_core_web_sm,但代码调用的是es_core_news_sm,会导致模型加载失败。
  • 调试代码报错:代码中使用spacy.displacy.render(doc, style="ent", jupyter=True),容器内无Jupyter环境,运行时会抛出异常。
  • 代码逻辑缩进错误:productosReconocidos初始化和自定义模型加载代码被包含在for frase循环内,会重复加载模型并导致逻辑混乱。

解决方案

1. 修改inference.py,实现SageMaker推理接口

使用Flask搭建HTTP服务,适配SageMaker规范,同时修正代码逻辑:

import spacy
from nltk.tokenize import sent_tokenize
import string
import es_core_news_sm
from flask import Flask, request, jsonify
import os

# SageMaker自动解压模型到/opt/ml/model目录
model_local_path = '/opt/ml/model'

# 提前加载模型,避免每次请求重复加载
nlp_preprocess = es_core_news_sm.load()
nlp_ner = spacy.load(model_local_path)

app = Flask(__name__)

def process_text(text):
    frasesSolicitud = sent_tokenize(text)
    frasesProcesadas = []
    
    for frase in frasesSolicitud:
        frasesSinVerbos = []
        texto = frase.lower()
        texto = texto.translate(str.maketrans('', '', string.punctuation))
        
        doc = nlp_preprocess(texto)
        for palabra in doc:
            if palabra.pos_ not in ['VERB', 'ADJ', 'PRON']:
                frasesSinVerbos.append(str(palabra))
        
        textoSinVerbos = ' '.join(frasesSinVerbos)
        frasesProcesadas.append(textoSinVerbos)
    
    productosReconocidos = []
    for item in frasesProcesadas:
        fraseProcesada = item.lower()
        doc = nlp_ner(fraseProcesada)
        # 移除Jupyter环境专属的调试代码
        for ent in doc.ents:
            productosReconocidos.append(ent.label_)
    
    return productosReconocidos

# 健康检查端点(SageMaker必选)
@app.route('/ping', methods=['GET'])
def ping():
    return jsonify({'status': 'healthy'}), 200

# 推理请求端点(SageMaker必选)
@app.route('/invocations', methods=['POST'])
def invocations():
    data = request.get_json()
    if 'text' not in data:
        return jsonify({'error': 'Missing "text" in request'}), 400
    
    text = data['text']
    result = process_text(text)
    return jsonify({'entities': result}), 200

if __name__ == '__main__':
    # 监听8080端口(SageMaker要求的默认端口)
    app.run(host='0.0.0.0', port=8080)

2. 修改Dockerfile,适配SageMaker规范

调整依赖安装逻辑,确保serve命令能正常启动服务,同时修正模型依赖:

FROM python:3.8-slim-bullseye

# 设置SageMaker要求的工作目录
WORKDIR /opt/ml/code

# 安装核心依赖
RUN pip install spacy nltk flask

# 安装系统依赖,清理缓存减小镜像体积
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    libatlas-base-dev \
    libcurl4-openssl-dev \
    libssl-dev && \
    rm -rf /var/lib/apt/lists/*

# 安装代码中实际使用的西班牙语SpaCy模型
RUN python -m spacy download es_core_news_sm

# 复制推理脚本到工作目录
COPY inference.py .

# SageMaker环境变量配置
ENV SAGEMAKER_PROGRAM inference.py
ENV PYTHONUNBUFFERED TRUE

# 启动命令:SageMaker执行serve时启动Flask服务
ENTRYPOINT ["python", "inference.py"]

3. 调整模型打包方式

确保上传到S3的model.tar.gz是训练后模型文件夹内所有内容的压缩包(而非包含模型文件夹本身),这样解压后/opt/ml/model目录下会直接包含模型的完整文件。

4. 本地测试容器(关键步骤)

在本地先验证容器功能,避免重复上传ECR:

# 构建本地镜像
docker build -t spacy-sagemaker .

# 模拟SageMaker启动命令运行容器
docker run -p 8080:8080 spacy-sagemaker serve

# 另一个终端测试健康检查
curl http://localhost:8080/ping

# 测试推理请求
curl -X POST http://localhost:8080/invocations -H "Content-Type: application/json" -d '{"text": "Tu texto de ejemplo aquí"}'

本地测试正常后,重新上传镜像到ECR,再在SageMaker中创建模型和端点即可。

内容的提问来源于stack exchange,提问作者DavDEV_02

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:33:15