返回文章列表

深度學習資料集管理服務設計與實作

本文探討深度學習資料集管理服務的設計與實作,涵蓋資料集結構設計、資料轉換器實作、以及 Delta Lake 和 Pachyderm 兩種開源方案的應用。文章以影像分類別為例,說明如何利用 Delta Lake 建立版本化資料集快照,並結合 Petastorm 將資料轉換為 PyTorch 和 TensorFlow

深度學習 資料工程

深度學習模型的訓練仰賴大量的資料,因此有效管理與處理資料集至關重要。本文首先介紹如何設計一個可擴充套件的資料集管理服務,並以影像分類別為例,說明如何設計資料集結構與實作資料轉換器。接著,文章探討兩種開源資料集管理方案:Delta Lake 與 Pachyderm。Delta Lake 結合 Apache Spark 提供版本控制、Schema 保護和時間旅行等功能,確保資料集的可重現性與一致性。Petastorm 則能將 Delta Lake 表格資料轉換為深度學習框架可用的格式,簡化模型訓練流程。另一方面,Pachyderm 是一個根據 Kubernetes 的資料管線工具,提供版本控制、自動化和資料來源追蹤功能,適用於構建端對端的機器學習流程。文章比較了 Delta Lake 和 Pachyderm 的優缺點,並提供程式碼範例,展示如何使用這些工具構建高效的深度學習資料集管理流程。

資料集管理服務的設計與實作

資料集結構與型別

在設計資料集管理服務時,定義良好的資料集結構至關重要。以影像分類別資料集為例,其目錄結構如下:

60 C HAPTER 2 Dataset management service
└── dog
    ├── dogA.jpg
    ├── dogB.jpg
    └── dogC.jpg

這種結構便於管理和擴充套件不同型別的資料集。

實作資料集轉換器

要支援新的資料集型別,需要建立一個實作DatasetTransformer介面的類別,例如ImageClassTransformer。這個類別負責實作資料的讀取和寫入邏輯。

ingest()函式的實作

ingest()函式負責解析輸入資料,將其轉換為訓練資料格式,並儲存為資料集的提交(commit)。

compress()函式的實作

compress()函式首先根據資料過濾器選擇提交(commit),然後將匹配的提交合併成一個訓練快照(snapshot)。最後,將ImageClassTransformeringest()compress()函式註冊到相應的資料集處理流程中。

服務設計回顧

本文回顧了樣本資料集管理服務如何滿足五項設計原則:

  1. 支援資料集可重現性:透過儲存所有生成的訓練資料作為版本化的快照,用版本雜湊字串作為鍵,使用者可以隨時取得特定版本的訓練資料。
  2. 提供統一的體驗:資料攝入API和訓練資料取得API對所有資料集型別和大小都以相同的方式工作。
  3. 採用強型別資料模式:樣本中的TEXT_INTENTIMAGE_CLASS型別資料集對原始攝入資料和訓練資料都應用了自定義的資料模式。
  4. 確保API一致性並內部處理擴充套件:雖然樣本程式碼為了簡單起見將所有資料集的後設資料儲存在記憶體中,但理論上可以輕易地將資料集儲存結構實作在雲物件儲存中,具有無限容量。
  5. 保證資料永續性:每個資料集建立請求和更新請求都會建立新的提交;每個訓練資料準備請求都會建立版本化的快照。提交和快照都是不可變的,並且持久儲存,沒有資料過期限制。

開源方法

對於希望採用開源方法來建立資料集管理功能的讀者,本文介紹了兩種方法:Delta Lake和Pachyderm。

Delta Lake與Petastorm結合Apache Spark家族

Delta Lake是一個儲存層,為Apache Spark和其他雲物件儲存帶來可擴充套件的ACID事務。Petastorm函式庫則用於將Delta Lake表格資料轉換為PyTorch和TensorFlow資料集物件,從而在訓練程式碼中無縫使用。

Delta Lake的核心概念
  • Delta Lake表格:系統的核心概念,類別似於SQL表格,可以查詢、插入、更新和合併表格內容。
  • 模式保護:支援表格寫入時的模式驗證,防止資料汙染。
  • 時間旅行:跟蹤表格歷史,可以回復到過去的任何階段。
構建資料處理管道

Delta Lake建議將表格命名為三類別:bronze、silver和gold。bronze表格儲存來自不同來源的原始輸入資料;silver表格進行資料清洗和轉換;gold表格則進一步最佳化,用於特定的應用場景。

深度學習資料集管理的最佳選擇:Delta Lake

在深度學習專案中,資料集管理是至關重要的環節。Delta Lake 是一種優秀的資料集管理工具,它提供了多項強大的功能,使其成為深度學習專案的理想選擇。

為什麼 Delta Lake 是深度學習資料集管理的最佳選擇?

Delta Lake 的三大特色使其成為管理深度學習資料集的理想工具。首先,它支援資料集的可重現性。Delta Lake 的「時間旅行」功能允許使用者查詢特定時間點的資料版本。假設您設定了一個持續執行的 ETL 管道來保持訓練資料集(gold table)更新,由於 Delta Lake 將表格更新記錄為快照,每個操作都會自動版本化。這意味著所有的訓練資料快照都會被保留,您可以輕鬆瀏覽表格更新歷史並回復到過去的階段。

pathToTable = "/my/sample/text/intent/dataset/A"
deltaTable = DeltaTable.forPath(spark, pathToTable)
fullHistoryDF = deltaTable.history()
lastOperationDF = deltaTable.history(1)
df = spark.read.format("delta")
    .option("timestampAsOf", "2021-07-01")
    .load(pathToTable)

內容解密:

  1. deltaTable.history():取得資料表的完整歷史記錄。
  2. deltaTable.history(1):取得最近一次的操作記錄。
  3. spark.read.format("delta").option("timestampAsOf", "2021-07-01").load(pathToTable):根據時間戳記回復資料表至特定版本。

其次,Delta Lake 支援持續的串流資料處理。其表格可以無縫地處理來自歷史和即時串流來源的連續資料流。例如,您的資料管道或串流資料來源可以在查詢資料表的同時不斷向 Delta Lake 表格新增資料。這省去了編寫程式碼以合併新資料與現有資料的額外步驟。

第三,Delta Lake 提供了架構執行和演進功能。它在寫入時進行架構驗證,確保新資料記錄與表格的預定義架構相符;如果新資料與表格的架構不相容,Delta Lake 將引發例外。除了強大的架構執行外,Delta Lake 還允許您在不引起破壞性變更的情況下向現有資料表格新增新欄位。

Petastorm:開放原始碼的資料存取函式庫

Petastorm 是 Uber ATG(Advanced Technologies Group)開發的開放原始碼資料存取函式庫。它使單機或分散式訓練和評估深度學習模型可以直接從 Apache Parquet 格式的資料集中進行。

Petastorm 可以輕鬆地將 Delta Lake 表格轉換為 Tensorflow 和 PyTorch 格式的資料集,並支援分散式訓練資料分割槽。透過 Petastorm,來自 Delta Lake 表格的訓練資料可以簡單地被下游訓練應用程式使用,而不必擔心特定訓練框架的資料轉換細節。

# Petastorm 的資料轉換流程

內容解密:

  1. Petastorm 將 Delta Lake 表格轉換為 Parquet 檔案。
  2. 將 Parquet 檔案轉換為 Tensorflow 或 PyTorch 資料集。

範例:為花卉影像分類別準備訓練資料

現在我們對 Delta Lake 和 Petastorm 有了初步瞭解,讓我們看看一個具體的模型訓練範例。下面的程式碼片段(程式碼清單 2.13 和 2.14)展示了影像分類別模型訓練工作流程的兩個步驟。

首先,它們定義了一個影像處理 ETL 管道,將一組影像檔案解析為 Delta Lake 表格作為影像資料集。其次,它們使用 Petastorm 將 Delta Lake 表格轉換為可以直接載入到 PyTorch 框架中的資料集,以開始模型訓練。


## 步驟 1:載入所有原始影像檔案
path_labeled_rawdata = "datacollablab/flower_photos/"
images = spark.read.format("binary")
    .option("recursiveFileLookup", "true")
    .option("pathGlobFilter", "*.jpg")
    .load(path_labeled_rawdata)
    .repartition(4)

## 步驟 2:定義 ETL 提取函式
def extract_label(path_col):
    """從檔案路徑中使用內建 SQL 函式提取標籤。"""
    return regexp_extract(path_col, "flower_photos/([^/]+)", 1)

def extract_size(content):
    """從原始內容中提取影像大小。"""
    image = Image.open(io.BytesIO(content))
    return image.size

@pandas_udf("width: int, height: int")
def extract_size_udf(content_series):
    sizes = content_series.apply(extract_size)
    return pd.DataFrame(list(sizes))

內容解密:

  1. spark.read.format("binary").load(path_labeled_rawdata):以二進位檔案格式讀取影像檔案。
  2. extract_labelextract_size:定義提取函式以取得影像標籤和大小。
  3. extract_size_udf:使用 pandas UDF 提取影像大小。

步驟3:建構並執行ETL以生成包含標籤、影像、影像大小和路徑的資料框架

df = images.select( col(“path”), extract_size_udf(col(“content”)).alias(“size”), extract_label(col(“path”)).alias(“label”), col(“content”) )

步驟4:將ETL產生的影像資料框架儲存到Delta Lake表格

gold_table_training_dataset = “datacollablab.flower_train_binary” spark.conf.set(“spark.sql.parquet.compression.codec”, “uncompressed”) df.write.format(“delta”).mode(“overwrite”) .saveAsTable(gold_table_training_dataset)

內容解密:

  1. images.select:從images資料框架中選擇需要的欄位。
  2. extract_size_udf(col("content")).alias("size"):使用使用者自定義函式extract_size_udf提取影像大小,並將結果命名為size
  3. extract_label(col("path")).alias("label"):根據影像路徑提取標籤,並將結果命名為label
  4. df.write.format("delta").mode("overwrite"):將資料框架以Delta格式寫入,並覆寫現有資料。

現在,我們已經在Delta Lake表格中建立了影像資料集,可以開始使用Petastorm訓練PyTorch模型。

步驟1:從Delta Lake表格讀取資料框架

df = spark.read.format(“delta”) .load(gold_table_training_dataset) .select(col(“content”), col(“label_index”)) .limit(100) num_classes = df.select(“label_index”).distinct().count() df_train, df_val = df.randomSplit([0.9, 0.1], seed=12345)

步驟2:將資料框架載入Petastorm轉換器

spark.conf.set(SparkDatasetConverter.PARENT_CACHE_DIR_URL_CONF, “file:///dbfs/tmp/petastorm/cache”) converter_train = make_spark_converter(df_train) converter_val = make_spark_converter(df_val)

步驟3:使用Petastorm轉換器讀取PyTorch訓練資料

def train_and_evaluate(lr=0.001): device = torch.device(“cuda”) model = get_model(lr=lr) # … with converter_train.make_torch_dataloader( transform_spec=get_transform_spec(is_train=True), batch_size=BATCH_SIZE) as train_dataloader, converter_val.make_torch_dataloader( transform_spec=get_transform_spec(is_train=False), batch_size=BATCH_SIZE) as val_dataloader: # …

內容解密:

  1. spark.read.format("delta").load(gold_table_training_dataset):從Delta Lake表格讀取資料框架。
  2. df.randomSplit([0.9, 0.1], seed=12345):將資料框架分割為訓練集和驗證集。
  3. make_spark_converter(df_train):將訓練集資料框架轉換為Petastorm轉換器。
  4. converter_train.make_torch_dataloader:使用Petastorm轉換器建立PyTorch資料載入器。

何時使用Delta Lake

常見的誤解是Delta Lake只能處理結構化的文字資料,但上述範例表明它也可以處理非結構化的資料,如影像和音訊檔案。Delta Lake是進行資料集管理的絕佳選擇,如果您已經使用Apache Spark建立資料管線。

Delta Lake的限制

使用Delta Lake的最大風險是技術鎖定和陡峭的學習曲線。Delta Lake儲存表格在其自己的機制中,需要使用Delta ACID API進行資料擷取和Delta JDBC執行查詢。因此,如果您決定將來遷移離開Delta Lake,資料遷移成本將很高。

Pachyderm與雲端物件儲存

在本文中,我們提出了一個輕量級的、根據Kubernetes的工具——Pachyderm——來處理資料集管理。Pachyderm是一種用於建立版本控制、自動化、端對端資料管線的工具,適用於資料科學。

Pachyderm

Pachyderm是一個用於建立版本控制、自動化、端對端資料管線的工具,適用於資料科學。它執行在Kubernetes上,並由您選擇的物件儲存(例如Amazon S3)支援。您可以編寫自己的Docker映像進行資料擷取、清理、處理,並使用Pachyderm管線將它們串聯起來。

內容解密:

  1. Pachyderm提供資料集版本控制和來源管理。
  2. Pachyderm將每個資料更新視為一次提交,並跟蹤生成資料更新的資料來源。
  3. Pachyderm管線執行各種資料轉換,使用者可以定義自己的Docker容器來執行特定的任務。

資料集管理服務:Pachyderm 的應用與實踐

Pachyderm 的核心概念

Pachyderm 是一個資料集管理服務,它允許使用者建立資料處理流程(pipeline),並且自動化地執行資料處理任務。每當資料集中有新的資料加入時,Pachyderm 就會啟動一個作業(job)來處理這些資料。

Pachyderm 的工作原理

Pachyderm 的工作原理可以透過一個簡單的 pipeline 定義來說明。如下所示:

{
  "pipeline": {
    "name": "edges"
  },
  "description": "A pipeline that performs image edge detection by using the OpenCV library.",
  "transform": {
    "cmd": [ "python3", "/edges.py" ],
    "image": "pachyderm/opencv"
  },
  "input": {
    "pfs": {
      "repo": "images",
      "glob": "/*"
    }
  }
}

這個 pipeline 名為 “edges”,它監控著一個名為 “images” 的資料集。當有新的影像加入到 “images” 資料集中時,pipeline 就會啟動一個作業,使用 pachyderm/opencv Docker 映象來解析影像,並將生成的邊緣檢測結果儲存到 “edges” 資料集中。

內容解密:

  1. pipeline: 定義了 pipeline 的名稱和描述。
  2. transform: 指定了處理資料的命令和使用的 Docker 映象。
  3. input: 定義了 pipeline 的輸入資料,即 “images” 資料集。

版本控制與資料來源追蹤

Pachyderm 自動對資料集和 pipeline 的變更進行版本控制,使用者可以使用 pachctl 命令列工具來檢查檔案的歷史記錄,甚至回復變更。

例如,使用 pachctl list commit edges 命令可以列出 “edges” 資料集的所有提交記錄:

$ pachctl list commit edges
REPO    BRANCH  COMMIT                              FINISHED
edges   master  0547b62a0b6643adb370e80dc5edde9f    3 minutes ago
edges   master  eb58294a976347abaf06e35fe3b0da5b    3 minutes ago
edges   master  f06bc52089714f7aa5421f8877f93b9c    7 minutes ago

使用 pachctl inspect commit 命令可以檢查特定提交的詳細資訊,包括資料來源:

$ pachctl inspect commit edges@eb58294a976347abaf06e35fe3b0da5b --full-timestamps

輸出結果顯示了該提交的詳細資訊,包括其來源:

Commit: edges@eb58294a976347abaf06e35fe3b0da5b
Original Branch: master
Parent: f06bc52089714f7aa5421f8877f93b9c
Started: 2021-07-19T05:04:23.652132677Z
Finished: 2021-07-19T05:04:26.867797209Z
Size: 59.38KiB
Provenance: __spec__@91da2f82607b4c40911d48be99fd3031 (edges)
           images@66f4ff89a017412090dc4a542d9b1142 (master)

內容解密:

  1. Commit: 提交的唯一識別符號。
  2. Provenance: 該提交的資料來源,即由哪個資料集的哪個提交生成。

使用 Pachyderm 自動化物件檢測模型的訓練

Pachyderm 可以用來自動化物件檢測模型的訓練流程。整個流程包括兩個 pipeline:標註 pipeline 和訓練 pipeline,以及兩個資料集:原始影像資料集和標註資料集。

自動化流程:

  1. 上傳原始影像到 “raw image dataset”。
  2. 啟動標註 pipeline,對原始影像進行標註,並將標註結果儲存到 “labeled dataset”。
  3. 當 “labeled dataset” 有新的資料加入時,自動啟動訓練 pipeline,開始模型訓練。
  4. 將訓練好的模型檔案儲存起來。

Pachyderm 自動對整個流程中的資料進行版本控制,並且透過資料來源追蹤功能,可以清晰地瞭解到每個模型檔案是由哪個版本的標註資料集訓練而來。

Pachyderm 的優勢與侷限

優勢:

  • 輕量級,易於搭建和維護。
  • 以資料科學家為中心,易於使用。
  • 支援 Git 風格的資料版本控制。
  • 適合處理非結構化資料,如影像和音訊檔案。

侷限:

  • 缺乏 schema 保護和資料分析效率。
  • 將所有資料視為檔案,不關心檔案內容,可能導致資料一致性問題。