4. 数据接入与数据集管理
在Azure机器学习项目中,数据接入不是“把文件拷进工作区”这么简单。真正决定项目能否复现、能否审计、能否安全协作的,是数据如何被引用、如何被版本化,以及每次训练到底用了哪一份数据。Azure ML 通过数据资产(Data Asset)与数据存储(Datastore)两层抽象来解决这个问题:Datastore 保存连接信息(凭据、端点、容器),Data Asset 则指向具体的数据路径或查询,并携带版本、描述和血缘信息。本节围绕 Blob、Data Lake、SQL 三类典型源,说明如何创建、消费和追踪数据集。
一、Datastore:先建立“连接”,再谈数据
Datastore 是工作区级别的连接对象,它把存储账户、容器/文件系统、凭据封装起来,避免在脚本里硬编码密钥。常见类型包括 Azure Blob、Azure Data Lake Storage Gen2、Azure SQL Database、Azure Files 等。创建时通常需要提供存储账户名、容器名、认证方式(账户密钥、SAS、服务主体或工作区托管标识)。
以 Blob 为例,使用 CLI 注册一个 Datastore 的典型命令如下(示例参数,实际需替换为你的账户信息):
az ml datastore create \
--file datastore-blob.yml \
--resource-group rg-ml-dev \
--workspace-name mlw-dev
# datastore-blob.yml 关键字段
name: ds_blob_raw
type: azure_blob
account_name: stmldev001
container_name: raw-data
credentials:
account_key: <key>
对于 Data Lake Gen2,类型改为 azure_data_lake_gen2,并指定 filesystem;对于 SQL,类型为 azure_sql_database,需要提供 server_name、database_name、username、password。Datastore 一旦注册,后续所有数据资产都可以用 azureml://datastores/<name>/paths/<path> 这种 URI 引用,脚本与具体存储解耦。
二、从三类源创建数据资产
数据资产分为 File(单个文件或一组文件)和 Table(表格型,通常来自 SQL 或 Parquet/CSV)。创建方式有 SDK、CLI 和 Studio 界面。下面用 SDK 展示三种源的创建逻辑。
from azure.ai.ml.entities import Data
from azure.ai.ml.constants import AssetTypes
# 1) Blob:指向一个 CSV 文件
blob_data = Data(
name="raw_customer_csv",
version="1",
path="azureml://datastores/ds_blob_raw/paths/customer/2024-06/customer.csv",
type=AssetTypes.URI_FILE,
description="客户原始表,2024年6月批次"
)
# 2) Data Lake Gen2:指向一个目录(多文件)
lake_data = Data(
name="raw_orders_parquet",
version="1",
path="azureml://datastores/ds_lake_raw/paths/orders/year=2024/month=06/",
type=AssetTypes.URI_FOLDER,
description="订单 Parquet 分区目录"
)
# 3) SQL:用 SQL 查询定义表型资产
sql_data = Data(
name="dim_product_sql",
version="1",
path="SELECT product_id, product_name, category, price FROM dbo.dim_product",
type=AssetTypes.MLTABLE,
description="产品维表,来自 Azure SQL"
)
创建后,每个资产都有唯一的 name:version 标识,例如 raw_customer_csv:1。版本号可以手动指定,也可以让系统自动递增。关键点是:版本一旦发布,内容应视为不可变。如果数据更新,应创建新版本(如 raw_customer_csv:2),而不是覆盖旧路径,否则历史训练将无法复现。
三、在训练脚本中消费数据资产
消费方式取决于资产类型。File/Folder 型资产通常作为输入挂载或下载到本地路径;Table 型资产可直接读取为 pandas DataFrame。
from azure.ai.ml import Input, command
job = command(
code="./src",
command="python train.py --data ${{inputs.customer_data}}",
inputs={
"customer_data": Input(
type="uri_file",
path="azureml:raw_customer_csv:1"
)
},
environment="AzureML-sklearn-1.0-ubuntu20.04-py38-cpu:33",
compute="cpu-cluster"
)
在 train.py 中,--data 参数会收到一个本地路径(挂载模式)或已下载路径。对于 Table 资产,可用 mltable 或 to_pandas_dataframe() 读取。这样,训练任务与数据版本通过 azureml:name:version 显式绑定,血缘关系自动记录。
四、版本化与血缘追踪的实际价值
Azure ML 会自动记录数据资产与作业、模型之间的血缘关系。你可以在 Studio 中打开某个模型,查看它由哪个作业产生、该作业又消费了哪些数据资产及版本。反过来,从数据资产也能看到哪些作业引用了它。这种双向追踪在以下场景中非常关键:
- 复现实验:模型指标异常时,确认训练时用的数据版本是否被误改。
- 审计合规:证明某次预测所依据的数据来源和转换链路。
- 影响分析:上游数据更新后,快速定位哪些模型需要重新训练。
需要特别注意的是,血缘追踪依赖“通过 Azure ML 资产引用数据”这一前提。如果脚本里直接写 pd.read_csv("https://stmldev001.blob.core.windows.net/..."),系统无法自动捕获这层关系。因此,工程上应坚持用 Datastore URI 或数据资产引用,而不是裸 URL。
五、版本命名与生命周期建议
版本号建议与数据批次或日期对齐,例如 v20240601 或直接使用递增整数并在描述中写明批次。对于 SQL 表型资产,如果查询逻辑变化(如新增字段),应发布新版本;如果只是底层表数据刷新,可考虑用同一查询创建新版本,以保持“查询定义”与“数据快照”的区分。删除旧版本前,先确认没有生产作业仍引用它,否则会导致作业失败。
description 和 tags 字段可以承载这些信息,便于团队检索。
把上述流程落到日常操作中,可以形成一条稳定的工作习惯:新数据到达时,先确认 Datastore 连接是否可用;然后按批次创建或更新数据资产版本,并在描述中写清来源和用途;训练脚本一律通过 azureml:name:version 引用数据;最后在模型注册时检查血缘页面,确认数据版本与预期一致。这样,数据接入就不再是一次性的搬运,而是可追踪、可复现、可协作的工程环节。