ML Metadata

ML Metadata (MLMD) 是一個程式庫,可用於記錄及擷取與 ML 開發人員和資料科學家工作流程相關聯的中繼資料。MLMD 是 TensorFlow Extended (TFX) 的一部分,但其設計宗旨是可獨立使用。

生產 ML 管線的每次執行都會產生中繼資料,其中包含關於各種管線元件、其執行 (例如訓練執行) 和產生的成品 (例如已訓練模型) 的資訊。如果發生非預期的管線行為或錯誤,可以運用這些中繼資料來分析管線元件的沿襲並偵錯問題。將此中繼資料視為軟體開發中的記錄檔同等重要。

MLMD 可協助您瞭解及分析 ML 管線的所有相互關聯部分,而非隔離分析這些部分,並可協助您回答關於 ML 管線的問題,例如

  • 模型是以哪個資料集進行訓練?
  • 訓練模型時使用了哪些超參數?
  • 哪個管線執行作業建立了模型?
  • 哪個訓練執行作業產生此模型?
  • 哪個 TensorFlow 版本建立了此模型?
  • 失敗模型是在何時推送?

中繼資料儲存區

MLMD 會在中繼資料儲存區這個資料庫中,註冊下列類型中繼資料。

  1. 關於透過 ML 管線的元件/步驟產生的成品的的中繼資料
  2. 關於這些元件/步驟的執行的中繼資料
  3. 關於管線和相關沿襲資訊的中繼資料

中繼資料儲存區提供 API,可用於記錄中繼資料,以及從儲存空間後端擷取中繼資料。儲存空間後端可外掛且可擴充。MLMD 提供 SQLite (支援記憶體內和磁碟) 和 MySQL 的參考實作,可立即使用。

下圖顯示 MLMD 所含各種元件的高階總覽。

ML Metadata Overview

中繼資料儲存空間後端和儲存區連線設定

MetadataStore 物件會接收與所用儲存空間後端對應的連線設定。

  • Fake Database 提供記憶體內資料庫 (使用 SQLite),以便快速實驗及在本機執行。當儲存區物件遭到損毀時,資料庫就會遭到刪除。
import ml_metadata as mlmd
from ml_metadata.metadata_store import metadata_store
from ml_metadata.proto import metadata_store_pb2

connection_config = metadata_store_pb2.ConnectionConfig()
connection_config.fake_database.SetInParent() # Sets an empty fake database proto.
store = metadata_store.MetadataStore(connection_config)
  • SQLite 會從磁碟讀取及寫入檔案。
connection_config = metadata_store_pb2.ConnectionConfig()
connection_config.sqlite.filename_uri = '...'
connection_config.sqlite.connection_mode = 3 # READWRITE_OPENCREATE
store = metadata_store.MetadataStore(connection_config)
  • MySQL 連線至 MySQL 伺服器。
connection_config = metadata_store_pb2.ConnectionConfig()
connection_config.mysql.host = '...'
connection_config.mysql.port = '...'
connection_config.mysql.database = '...'
connection_config.mysql.user = '...'
connection_config.mysql.password = '...'
store = metadata_store.MetadataStore(connection_config)

同樣地,當搭配 Google CloudSQL 使用 MySQL 執行個體 (快速入門連線總覽) 時,也可以在適用的情況下使用 SSL 選項。

connection_config.mysql.ssl_options.key = '...'
connection_config.mysql.ssl_options.cert = '...'
connection_config.mysql.ssl_options.ca = '...'
connection_config.mysql.ssl_options.capath = '...'
connection_config.mysql.ssl_options.cipher = '...'
connection_config.mysql.ssl_options.verify_server_cert = '...'
store = metadata_store.MetadataStore(connection_config)
  • PostgreSQL 連線至 PostgreSQL 伺服器。
connection_config = metadata_store_pb2.ConnectionConfig()
connection_config.postgresql.host = '...'
connection_config.postgresql.port = '...'
connection_config.postgresql.user = '...'
connection_config.postgresql.password = '...'
connection_config.postgresql.dbname = '...'
store = metadata_store.MetadataStore(connection_config)

同樣地,當搭配 Google CloudSQL 使用 PostgreSQL 執行個體 (快速入門連線總覽) 時,也可以在適用的情況下使用 SSL 選項。

connection_config.postgresql.ssloption.sslmode = '...' # disable, allow, verify-ca, verify-full, etc.
connection_config.postgresql.ssloption.sslcert = '...'
connection_config.postgresql.ssloption.sslkey = '...'
connection_config.postgresql.ssloption.sslpassword = '...'
connection_config.postgresql.ssloption.sslrootcert = '...'
store = metadata_store.MetadataStore(connection_config)

資料模型

中繼資料儲存區使用下列資料模型,從儲存空間後端記錄及擷取中繼資料。

  • ArtifactType 說明成品的類型及其屬性,這些屬性會儲存在中繼資料儲存區中。您可以在程式碼中使用中繼資料儲存區動態註冊這些類型,也可以從序列化格式將這些類型載入儲存區中。一旦您註冊類型,其定義在儲存區的整個生命週期內都可用。
  • Artifact 說明 ArtifactType 的特定執行個體,以及寫入中繼資料儲存區的屬性。
  • ExecutionType 說明工作流程中元件或步驟的類型及其執行階段參數。
  • Execution 是 ML 工作流程中元件執行或步驟的記錄,以及執行階段參數。執行可以視為 ExecutionType 的執行個體。當您執行 ML 管線或步驟時,系統會記錄執行。
  • Event 是成品和執行之間關係的記錄。當執行發生時,事件會記錄執行使用的每個成品,以及產生的每個成品。這些記錄可讓您在整個工作流程中追蹤沿襲。藉由查看所有事件,MLMD 就能瞭解發生了哪些執行,以及結果產生了哪些成品。然後,MLMD 可以從任何成品遞迴回溯到其所有上游輸入。
  • ContextType 說明工作流程中成品和執行的概念群組類型,以及其結構屬性。例如:專案、管線執行、實驗、擁有者等。
  • Context 是 ContextType 的執行個體。它會擷取群組內的共用資訊。例如:專案名稱、變更清單提交 ID、實驗註解等。它在 ContextType 內具有使用者定義的專屬名稱。
  • Attribution 是成品和情境之間關係的記錄。
  • Association 是執行和情境之間關係的記錄。

MLMD 功能

追蹤 ML 工作流程中所有元件/步驟的輸入和輸出及其沿襲,可讓 ML 平台啟用多項重要功能。以下清單概略列出部分主要優點。

  • 列出特定類型的所有成品。範例:所有已訓練的模型。
  • 載入兩個相同類型的成品以進行比較。範例:比較兩個實驗的結果。
  • 顯示情境中所有相關執行及其輸入和輸出成品的 DAG。範例:視覺化實驗的工作流程,以便進行偵錯和探索。
  • 遞迴回溯所有事件,以查看成品的建立方式。範例:查看哪些資料進入模型;強制執行資料保留計畫。
  • 找出使用指定成品建立的所有成品。範例:查看從特定資料集訓練的所有模型;根據不良資料標記模型。
  • 判斷執行是否先前已針對相同輸入執行過。範例:判斷元件/步驟是否已完成相同工作,以及是否可以直接重複使用先前的輸出。
  • 記錄及查詢工作流程執行的情境。範例:追蹤工作流程執行所用的擁有者和變更清單;依實驗分組沿襲;依專案管理成品。
  • 關於屬性和單躍點鄰近節點的宣告式節點篩選功能。範例:尋找某種類型且在某些管線情境下的成品;傳回類型成品,其中指定屬性的值在範圍內;尋找情境中具有相同輸入的先前執行。

請參閱 MLMD 教學課程,瞭解如何使用 MLMD API 和中繼資料儲存區來擷取沿襲資訊的範例。

將 ML Metadata 整合至 ML 工作流程

如果您是平台開發人員,並對將 MLMD 整合至系統感興趣,請使用以下範例工作流程,運用低階 MLMD API 來追蹤訓練工作的執行。您也可以在筆記本環境中使用高階 Python API 來記錄實驗中繼資料。

ML Metadata Example Flow

1) 註冊成品類型

# Create ArtifactTypes, e.g., Data and Model
data_type = metadata_store_pb2.ArtifactType()
data_type.name = "DataSet"
data_type.properties["day"] = metadata_store_pb2.INT
data_type.properties["split"] = metadata_store_pb2.STRING
data_type_id = store.put_artifact_type(data_type)

model_type = metadata_store_pb2.ArtifactType()
model_type.name = "SavedModel"
model_type.properties["version"] = metadata_store_pb2.INT
model_type.properties["name"] = metadata_store_pb2.STRING
model_type_id = store.put_artifact_type(model_type)

# Query all registered Artifact types.
artifact_types = store.get_artifact_types()

2) 註冊 ML 工作流程中所有步驟的執行類型

# Create an ExecutionType, e.g., Trainer
trainer_type = metadata_store_pb2.ExecutionType()
trainer_type.name = "Trainer"
trainer_type.properties["state"] = metadata_store_pb2.STRING
trainer_type_id = store.put_execution_type(trainer_type)

# Query a registered Execution type with the returned id
[registered_type] = store.get_execution_types_by_id([trainer_type_id])

3) 建立 DataSet ArtifactType 的成品

# Create an input artifact of type DataSet
data_artifact = metadata_store_pb2.Artifact()
data_artifact.uri = 'path/to/data'
data_artifact.properties["day"].int_value = 1
data_artifact.properties["split"].string_value = 'train'
data_artifact.type_id = data_type_id
[data_artifact_id] = store.put_artifacts([data_artifact])

# Query all registered Artifacts
artifacts = store.get_artifacts()

# Plus, there are many ways to query the same Artifact
[stored_data_artifact] = store.get_artifacts_by_id([data_artifact_id])
artifacts_with_uri = store.get_artifacts_by_uri(data_artifact.uri)
artifacts_with_conditions = store.get_artifacts(
      list_options=mlmd.ListOptions(
          filter_query='uri LIKE "%/data" AND properties.day.int_value > 0'))

4) 建立 Trainer 執行的執行

# Register the Execution of a Trainer run
trainer_run = metadata_store_pb2.Execution()
trainer_run.type_id = trainer_type_id
trainer_run.properties["state"].string_value = "RUNNING"
[run_id] = store.put_executions([trainer_run])

# Query all registered Execution
executions = store.get_executions_by_id([run_id])
# Similarly, the same execution can be queried with conditions.
executions_with_conditions = store.get_executions(
    list_options = mlmd.ListOptions(
        filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL'))

5) 定義輸入事件並讀取資料

# Define the input event
input_event = metadata_store_pb2.Event()
input_event.artifact_id = data_artifact_id
input_event.execution_id = run_id
input_event.type = metadata_store_pb2.Event.DECLARED_INPUT

# Record the input event in the metadata store
store.put_events([input_event])

6) 宣告輸出成品

# Declare the output artifact of type SavedModel
model_artifact = metadata_store_pb2.Artifact()
model_artifact.uri = 'path/to/model/file'
model_artifact.properties["version"].int_value = 1
model_artifact.properties["name"].string_value = 'MNIST-v1'
model_artifact.type_id = model_type_id
[model_artifact_id] = store.put_artifacts([model_artifact])

7) 記錄輸出事件

# Declare the output event
output_event = metadata_store_pb2.Event()
output_event.artifact_id = model_artifact_id
output_event.execution_id = run_id
output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT

# Submit output event to the Metadata Store
store.put_events([output_event])

8) 將執行標示為已完成

trainer_run.id = run_id
trainer_run.properties["state"].string_value = "COMPLETED"
store.put_executions([trainer_run])

9) 使用歸屬和判斷提示成品,將成品和執行分組在情境下

# Create a ContextType, e.g., Experiment with a note property
experiment_type = metadata_store_pb2.ContextType()
experiment_type.name = "Experiment"
experiment_type.properties["note"] = metadata_store_pb2.STRING
experiment_type_id = store.put_context_type(experiment_type)

# Group the model and the trainer run to an experiment.
my_experiment = metadata_store_pb2.Context()
my_experiment.type_id = experiment_type_id
# Give the experiment a name
my_experiment.name = "exp1"
my_experiment.properties["note"].string_value = "My first experiment."
[experiment_id] = store.put_contexts([my_experiment])

attribution = metadata_store_pb2.Attribution()
attribution.artifact_id = model_artifact_id
attribution.context_id = experiment_id

association = metadata_store_pb2.Association()
association.execution_id = run_id
association.context_id = experiment_id

store.put_attributions_and_associations([attribution], [association])

# Query the Artifacts and Executions that are linked to the Context.
experiment_artifacts = store.get_artifacts_by_context(experiment_id)
experiment_executions = store.get_executions_by_context(experiment_id)

# You can also use neighborhood queries to fetch these artifacts and executions
# with conditions.
experiment_artifacts_with_conditions = store.get_artifacts(
    list_options = mlmd.ListOptions(
        filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"')))
experiment_executions_with_conditions = store.get_executions(
    list_options = mlmd.ListOptions(
        filter_query=('contexts_a.id = {}'.format(experiment_id))))

搭配遠端 gRPC 伺服器使用 MLMD

您可以搭配遠端 gRPC 伺服器使用 MLMD,如下所示

  • 啟動伺服器
bazel run -c opt --define grpc_no_ares=true  //ml_metadata/metadata_store:metadata_store_server

根據預設,伺服器會為每個要求使用虛擬記憶體內資料庫,且不會在呼叫之間保存中繼資料。伺服器也可以透過 MLMD MetadataStoreServerConfig 進行設定,以便使用 SQLite 檔案或 MySQL 執行個體。設定可以儲存在文字 protobuf 檔案中,並透過 --metadata_store_server_config_file=path_to_the_config_file 傳遞至二進位檔。

文字 protobuf 格式的 MetadataStoreServerConfig 檔案範例

connection_config {
  sqlite {
    filename_uri: '/tmp/test_db'
    connection_mode: READWRITE_OPENCREATE
  }
}
  • 建立用戶端 Stub 並在 Python 中使用
from grpc import insecure_channel
from ml_metadata.proto import metadata_store_pb2
from ml_metadata.proto import metadata_store_service_pb2
from ml_metadata.proto import metadata_store_service_pb2_grpc

channel = insecure_channel('localhost:8080')
stub = metadata_store_service_pb2_grpc.MetadataStoreServiceStub(channel)
  • 搭配 RPC 呼叫使用 MLMD
# Create ArtifactTypes, e.g., Data and Model
data_type = metadata_store_pb2.ArtifactType()
data_type.name = "DataSet"
data_type.properties["day"] = metadata_store_pb2.INT
data_type.properties["split"] = metadata_store_pb2.STRING

request = metadata_store_service_pb2.PutArtifactTypeRequest()
request.all_fields_match = True
request.artifact_type.CopyFrom(data_type)
stub.PutArtifactType(request)

model_type = metadata_store_pb2.ArtifactType()
model_type.name = "SavedModel"
model_type.properties["version"] = metadata_store_pb2.INT
model_type.properties["name"] = metadata_store_pb2.STRING

request.artifact_type.CopyFrom(model_type)
stub.PutArtifactType(request)

資源

MLMD 程式庫具有高階 API,您可以輕鬆地搭配 ML 管線使用。詳情請參閱 MLMD API 文件

請查看 MLMD 宣告式節點篩選,瞭解如何使用 MLMD 宣告式節點篩選功能 (關於屬性和單躍點鄰近節點)。

另請查看 MLMD 教學課程,瞭解如何使用 MLMD 來追蹤管線元件的沿襲。

MLMD 提供公用程式,可處理跨版本結構定義和資料移轉。詳情請參閱 MLMD 指南