pipefunc:資料DAG管道快速構建工具

banq發表於2024-12-23


一個 Python 庫,旨在讓構建和執行復雜的計算工作流變得異常快速和簡單。如果您曾經處理過函式之間複雜的依賴關係,為並行化而苦苦掙扎,或者希望以更簡單的方式建立和管理DAG 管道,pipefunc那麼這裡可以為您提供幫助。


pipefunc使您能夠輕鬆地在 Python 中構建有向無環圖 (DAG)管道。它處理:

  1. 自動依賴解析: pipefunc智慧地確定函式的正確執行順序,無需手動進行依賴管理。
  2. 閃電般快速的執行:以最小的開銷(每個函式呼叫約 15 µs),pipefunc確保您的管道以極快的速度執行。
  3. 輕鬆並行化: pipefunc自動並行化獨立任務,無論是在本地機器還是 SLURM 叢集上。它支援任何concurrent.futures.Executor!
  4. 直觀的視覺化:生成互動式圖表來視覺化您的管道結構並瞭解資料流。
  5. 簡化的引數掃描: pipefunc該mapspec功能可讓您輕鬆定義和執行 N 維引數掃描,非常適合科學計算、模擬和超引數調整。
  6. 資源分析:透過詳細的 CPU、記憶體和時間報告深入瞭解管道的效能。
  7. 快取:避免使用多個快取後端進行冗餘計算。
  8. 型別註釋驗證:確保整個管道的型別一致性,以便儘早發現錯誤。
  9. 錯誤處理:包括ErrorSnapshot捕獲有關錯誤的詳細資訊的功能,使除錯更容易。

pipefunc適用於:

  • 科學計算:簡化模擬、資料分析和複雜的計算工作流程。
  • 機器學習:構建強大且可重複的 ML 管道,包括資料預處理、模型訓練和評估。
  • 資料工程:透過自動依賴管理和並行執行建立高效的 ETL 流程。
  • HPC:在 SLURM 叢集上執行pipefunc,對程式碼的更改很少。
  • 任何使用互連功能並希望改善程式碼組織、效能和可維護性的人。

pipefunc專為生產用途而設計,但它也是一個很好的原型設計和實驗工具。
比較:

  • Dask相比: pipefunc提供了一種更高階別、更具宣告性的方式來定義管道。它會根據您的函式定義和mapspecs 自動管理任務排程和執行,而無需您編寫顯式並行程式碼。
  • 與 Luigi/Airflow/Prefect/Kedro 相比:雖然這些工具在 ETL 和事件驅動工作流方面表現出色,但pipefunc專注於科學計算、模擬和計算工作流,其中對執行和資源分配的細粒度控制至關重要。此外,它的設定和開發方式更容易,依賴性最小!
  • Pandas相比:您可以輕鬆地與 結合使用pipefunc!Pandas用於pipefunc管理操作的執行Pandas並並行化資料處理管道。但它也可以與Polars、Xarray和其他庫很好地配合使用!
  • Joblib 相比:與 pipefunc相比,它具有多項優勢Joblib。pipefunc它可自動確定函式的執行順序、生成管道的互動式視覺化效果、分析資源使用情況並支援多個快取後端。此外,pipefunc它還允許您使用 s 指定輸入和輸出之間的對映mapspec,從而實現複雜的 map-reduce 操作。

例子:
pipefunc 提供了一個 Pipeline 類,您可以使用它來定義函式管道。您可以使用pipefunc裝飾器將函式新增到管道,裝飾器還允許您指定函式的輸出名稱。定義管道後,您可以針對特定輸出值執行它,透過組合函式節點來簡化它,將其視覺化為有向圖,並分析管道函式的資源使用情況。有關更詳細的使用說明和示例,請檢視包中提供的使用示例。

下面是 pipefunc 的一個簡單示例用法,用於說明其主要功能:

from pipefunc import pipefunc, Pipeline

@pipefunc(output_name=<font>"c")
def add(a, b):
    return a + b

@pipefunc(output_name=
"d")
def multiply(b, c):
    return b * c

pipeline = Pipeline([add, multiply])
result = pipeline(
"d", a=2, b=3)  # Automatically executes 'add' first
print(result)  # Output: 15

pipeline.visualize() # Visualize the pipeline

使用 mapspec 的並行示例:

import numpy as np
from pipefunc import pipefunc, Pipeline
from pipefunc.map import load_outputs

@pipefunc(output_name=<font>"c", mapspec="a[i], b[j] -> c[i, j]")
def f(a: int, b: int):
    return a + b

@pipefunc(output_name=
"mean") # no mapspec, so receives 2D `c[:, :]`
def g(c: np.ndarray):
    return np.mean(c)

pipeline = Pipeline([f, g])
inputs = {
"a": [1, 2, 3], "b": [4, 5, 6]}
result_dict = pipeline.map(inputs, run_folder=
"my_run_folder", parallel=True)
result = load_outputs(
"mean", run_folder="my_run_folder") # can load now too
print(result)  # Output: 7.0

 

相關文章