如何在Azure函数应用中加载Azure机器学习中已注册的模型?
如何在Azure函数应用中加载Azure机器学习中已注册的模型?
咱们先从你的迁移场景出发,你是从Azure容器实例(ACI)转到Azure Function做模型推理,之前的score.py用了init()和全局model变量,现在想知道Function里怎么调整对吧?我来一步步给你理清楚:
核心问题:init()和全局变量还需要吗?
这得分两种场景来看,核心取决于你的模型名称是不是动态依赖请求参数——也就是你当前的情况:模型名称是根据请求里的MachineName、HeadNumber、ProductEDP拼接出来的。这里有个关键限制:Azure Function的init()是实例冷启动时仅运行一次的初始化函数,运行时还没收到任何请求,根本拿不到这些动态参数,所以没法提前在init()里加载对应模型。
但如果你的模型是固定的,或者能提前枚举所有可能的模型名称,那init()+全局变量就非常有用——因为模型只需要加载一次,后续所有请求都能复用内存里的模型,性能会提升很多。
针对你当前动态模型场景的代码调整
因为你是根据请求参数动态生成模型名称,那只能在处理请求的main()函数里加载模型,但可以做一些小优化,同时保留你原来的核心加载逻辑:
调整后的完整代码
import pandas as pd import logging import os import azure.functions as func import joblib from azureml.core import Workspace from azureml.core.model import Model # 复用工作区初始化逻辑,避免重复创建连接 def get_ml_workspace(): # 推荐用托管标识授权,避免硬编码密钥 # 也可以从Function应用设置里读取工作区参数 try: ws = Workspace.from_config() # 如果本地调试用config.json,部署时可以用环境变量配置参数 # ws = Workspace(subscription_id=os.environ["AML_SUBSCRIPTION"], # resource_group=os.environ["AML_RG"], # workspace_name=os.environ["AML_WS"]) return ws except Exception as e: logging.error(f"Failed to connect to ML workspace: {str(e)}") raise def main(req: func.HttpRequest): logging.info("Python HTTP trigger function processed a request.") # 1. 解析并校验请求JSON try: dat = req.get_json() # 校验必填字段 required_fields = ["MachineName", "HeadNumber", "ProductEDP"] if not all(key in dat for key in required_fields): return func.HttpResponse( f"Missing required fields: {', '.join(required_fields)}", status_code=400 ) except (ValueError, TypeError): return func.HttpResponse( "Invalid or missing JSON data in request.", status_code=400 ) # 2. 动态生成模型名称并加载 model_name = f"{dat['MachineName']}_{dat['HeadNumber']}_{dat['ProductEDP']}_sfsw" try: ws = get_ml_workspace() model_path = Model.get_model_path(model_name=model_name, workspace=ws) model = joblib.load(model_path) logging.info(f"Successfully loaded model: {model_name}") except FileNotFoundError: return func.HttpResponse( f"Model '{model_name}' not found in Azure ML workspace.", status_code=404 ) except Exception as e: logging.error(f"Error loading model: {str(e)}") return func.HttpResponse( f"Internal error during model loading: {str(e)}", status_code=500 ) # 3. 这里加入你的模型推理逻辑 # 示例: # features = pd.DataFrame([dat["features"]]) # predictions = model.predict(features) # result = {"predictions": predictions.tolist()} return func.HttpResponse( "Model loaded successfully, inference completed.", status_code=200, mimetype="application/json" )
关键注意点
- 核心加载逻辑复用:你原来用的
Model.get_model_path和joblib.load完全可以复用,但要注意在Function环境里需要先初始化Azure ML工作区,推荐用托管标识给Function授权访问ML工作区,不要硬编码密钥。 - 全局变量的必要性:在当前动态模型场景下,单个全局
model变量其实没必要——因为每次请求加载的模型可能不同,每个请求是独立处理的。但如果想做缓存优化(比如同一个实例的后续请求用到同一个模型,就不用重新加载),可以用全局字典来缓存已加载的模型:
# 全局缓存字典,放在函数外部 model_cache = {} # 在main函数加载模型时: if model_name in model_cache: model = model_cache[model_name] else: model = joblib.load(model_path) model_cache[model_name] = model
这样同一个实例的后续请求如果用到相同模型,就能直接复用缓存,提升性能。
3. 依赖配置:一定要在Function的requirements.txt里添加所有需要的依赖包:
azure-functions pandas joblib azureml-core
优化方案:用init()预加载常用模型
如果你的业务场景里,常用的模型是固定的几个,或者可以提前枚举出来,那可以把这些常用模型在init()里预加载到全局缓存,后续请求直接复用:
import pandas as pd import logging import azure.functions as func import joblib from azureml.core import Workspace from azureml.core.model import Model model_cache = {} ws = None def init(): global ws logging.info("Initializing Function and preloading common models...") try: # 初始化ML工作区,只执行一次 ws = Workspace.from_config() # 预加载提前枚举的常用模型 common_model_names = ["machineA_head1_edpX_sfsw", "machineB_head2_edpY_sfsw"] for name in common_model_names: try: model_path = Model.get_model_path(model_name=name, workspace=ws) model_cache[name] = joblib.load(model_path) logging.info(f"Preloaded model: {name}") except Exception as e: logging.warning(f"Failed to preload model {name}: {str(e)}") except Exception as e: logging.error(f"Failed to initialize ML workspace: {str(e)}") def main(req: func.HttpRequest): global ws, model_cache # 后续逻辑和之前类似,先检查缓存,未命中再加载新模型...
最后补充权限与部署注意事项
- 托管标识权限:给Azure Function的系统分配/用户分配托管标识,添加Azure ML工作区的“机器学习数据科学家”或“贡献者”角色,确保
Model.get_model_path能正常访问模型。 - 冷启动缓解:如果模型体积较大,第一次加载会有冷启动延迟,缓存策略能有效降低重复加载的开销。
备注:内容来源于stack exchange,提问作者user14736700
相关产品推荐
相关产品推荐

