13.2. Поддержка Array API (экспериментальная)
Спецификация Array API определяет стандартный API для всех библиотек работы с массивами, имеющих API, подобный NumPy.
Некоторые оцениватели scikit-learn, которые для реализации алгоритмической логики своих методов fit, predict или transform опираются преимущественно на NumPy (а не на Cython), можно настроить для работы с любыми структурами входных данных, совместимыми с Array API. Такие оцениватели автоматически перенаправляют операции в соответствующее пространство имён, вместо того чтобы полагаться на NumPy.
На данном этапе эта поддержка считается экспериментальной, её необходимо явно включить с помощью конфигурации array_api_dispatch, и предполагается, что установлены последние версии библиотек. Подробности см. ниже.
В следующем видео представлен обзор принципов проектирования стандарта и того, как он упрощает взаимодействие между библиотеками для работы с массивами:
- Scikit-learn на GPU с Array API — доклад Thomas Fan на PyData NYC 2023.
13.2.1. Поддерживаемые библиотеки для работы с массивами
В следующей таблице перечислены библиотеки и аппаратные платформы, для которых мы регулярно проводим автоматические тесты на соответствие требованиям. Другие библиотеки и устройства, соответствующие Array API, также могут работать без дополнительной настройки.
Библиотека | Установка | Поддерживаемые устройства | Примечания |
|---|---|---|---|
CPU, GPU NVIDIA (CUDA), GPU Apple (MPS), GPU Intel (XPU) | См. Примечание о поддержке устройств MPS; см. Примечание о поддержке GPU Intel; см. Примечание о поддержке float64 на устройствах | ||
CUDA | |||
CPU, GPU Intel (SYCL) | Инструкции по настройке драйверов см. по ссылке для установки; см. Примечание о поддержке GPU Intel; см. Примечание о поддержке float64 на устройствах |
Ожидается, что со временем охват будет расширяться.
13.2.2. Включение поддержки Array API
Чтобы включить поддержку Array API, параметру конфигурации array_api_dispatch необходимо присвоить значение True. Рекомендуем задать этот параметр глобально, чтобы обеспечить единообразное поведение и предотвратить случайное смешивание пространств имён массивов. Обратите внимание: в примерах ниже мы используем менеджер контекста (config_context), чтобы не сбрасывать значение на False в конце каждого фрагмента кода и тем самым не влиять на остальную документацию.
Для поддержки стандарта Array API в scikit-learn необходимо до импорта scipy и scikit-learn установить переменную окружения SCIPY_ARRAY_API в значение 1:
export SCIPY_ARRAY_API=1
Обратите внимание: эта переменная окружения предназначена для временного использования. Подробнее см. в документации SciPy по Array API.
Для работы с Array API предполагается, что установлены последние версии зависимостей scikit-learn. Более старые версии могут работать, но мы этого не гарантируем. Хотя поддержка Array API отмечена как экспериментальная, обратная совместимость не гарантируется. В частности, если в новой версии зависимости исправлена ошибка, мы не будем добавлять дополнительный код для переноса исправления или поддержания совместимости со старыми версиями.
Scikit-learn принимает входные данные типа array-like для всех metrics и некоторых оценивателей. Если array_api_dispatch=False, эти данные преобразуются в массивы NumPy с помощью numpy.asarray (или numpy.array). Хотя таким способом успешно преобразуются некоторые входные данные Array API (например, массив JAX), при использовании таких входных данных мы обычно рекомендуем задавать array_api_dispatch=True. Это связано с тем, что преобразование в NumPy часто может завершиться ошибкой, например, для тензора torch, размещённого на GPU.
13.2.3. Пример использования
Приведённый ниже фрагмент кода демонстрирует, как использовать PyTorch для запуска LinearDiscriminantAnalysis на GPU CUDA:
>>> from sklearn.datasets import make_classification >>> from sklearn import config_context >>> from sklearn.discriminant_analysis import LinearDiscriminantAnalysis >>> import torch >>> X_np, y_np = make_classification(random_state=0) >>> X_torch = torch.asarray(X_np, device="cuda", dtype=torch.float32) >>> y_torch = torch.asarray(y_np, device="cuda", dtype=torch.float32) >>> with config_context(array_api_dispatch=True): ... lda = LinearDiscriminantAnalysis() ... X_trans = lda.fit_transform(X_torch, y_torch) >>> type(X_trans) <class 'torch.Tensor'> >>> X_trans.device.type 'cuda'
Этот подход работает одинаково с любой поддерживаемой библиотекой для работы с массивами. Например, замените torch.asarray(..., device="cuda") на cupy.asarray(...) для CuPy или на dpnp.asarray(...) для dpnp. В PyTorch также можно использовать другие устройства, изменив аргумент device= (например, "cpu", "xpu", "mps").
После обучения модели атрибуты обученного оценивателя, содержащие массивы, также будут принадлежать тому же пространству имён Array API, что и обучающие данные. Например, если для обучения использовалось пространство имён CUDA в PyTorch, атрибуты обученной модели будут находиться на GPU. Передача данных из другого пространства имён или с другого устройства в том же пространстве имён в transform или predict приводит к ошибке:
>>> with config_context(array_api_dispatch=True):
... lda.transform(X_np)
Traceback (most recent call last):
...
ValueError: Inputs passed to LinearDiscriminantAnalysis.transform() must use the same namespace and the same device as those passed to fit()...
13.2.3.1. Перенос оценивателей между устройствами
Для переноса атрибутов-массивов оценивателя в другое пространство имён и на другое устройство предусмотрен move_estimator_to:
>>> from sklearn.utils._array_api import move_estimator_to >>> import numpy as np >>> lda_np = move_estimator_to(lda, np, device="cpu") >>> with config_context(array_api_dispatch=True): ... X_trans = lda_np.transform(X_np) >>> type(X_trans) <class 'numpy.ndarray'>
13.2.4. Поддержка входных данных, совместимых с Array API
Оцениватели и другие инструменты scikit-learn, поддерживающие входные данные, совместимые с Array API.
13.2.4.1. Оцениватели
-
decomposition.PCA(сsvd_solver="full",svd_solver="covariance_eigh"илиsvd_solver="randomized"(svd_solver="randomized"только еслиpower_iteration_normalizer="QR")) kernel_approximation.Nystroem-
linear_model.LogisticRegression(сsolver="lbfgs") -
linear_model.PoissonRegressor(сsolver="lbfgs") -
linear_model.Ridge(сsolver="svd") -
linear_model.RidgeCV(см. Примечание о поддержке float64 на устройствах) -
linear_model.RidgeClassifier(сsolver="svd") -
linear_model.RidgeClassifierCV(см. Примечание о поддержке float64 на устройствах) -
discriminant_analysis.LinearDiscriminantAnalysis(сsolver="svd") naive_bayes.GaussianNBpreprocessing.Binarizerpreprocessing.KernelCenterer-
preprocessing.LabelBinarizer(сsparse_output=False) preprocessing.LabelEncoderpreprocessing.MaxAbsScalerpreprocessing.MinMaxScalerpreprocessing.Normalizerpreprocessing.PolynomialFeatures-
preprocessing.StandardScaler(см. Примечание о поддержке float64 на устройствах) -
mixture.GaussianMixture(сinit_params="random"илиinit_params="random_from_data"иwarm_start=False)
13.2.4.2. Метаоцениватели
Метаоцениватели принимают входные данные Array API при условии, что их базовый оцениватель также их поддерживает:
13.2.4.3. Метрики
sklearn.metrics.accuracy_scoresklearn.metrics.average_precision_scoresklearn.metrics.balanced_accuracy_scoresklearn.metrics.brier_score_losssklearn.metrics.calinski_harabasz_scoresklearn.metrics.cohen_kappa_scoresklearn.metrics.confusion_matrixsklearn.metrics.d2_absolute_error_scoresklearn.metrics.d2_brier_scoresklearn.metrics.d2_log_loss_scoresklearn.metrics.d2_pinball_scoresklearn.metrics.d2_tweedie_scoresklearn.metrics.det_curvesklearn.metrics.explained_variance_scoresklearn.metrics.f1_scoresklearn.metrics.fbeta_scoresklearn.metrics.hamming_losssklearn.metrics.jaccard_scoresklearn.metrics.log_losssklearn.metrics.max_errorsklearn.metrics.mean_absolute_errorsklearn.metrics.mean_absolute_percentage_errorsklearn.metrics.mean_gamma_deviancesklearn.metrics.mean_pinball_losssklearn.metrics.mean_poisson_deviancesklearn.metrics.mean_squared_errorsklearn.metrics.mean_squared_log_errorsklearn.metrics.mean_tweedie_deviancesklearn.metrics.median_absolute_errorsklearn.metrics.multilabel_confusion_matrixsklearn.metrics.pairwise.additive_chi2_kernelsklearn.metrics.pairwise.chi2_kernelsklearn.metrics.pairwise.cosine_similaritysklearn.metrics.pairwise.cosine_distances-
sklearn.metrics.pairwise_distances(поддерживаются только метрики «cosine», «euclidean», «manhattan» и «l2») sklearn.metrics.pairwise_distances_argmin-
sklearn.metrics.pairwise.euclidean_distances(см. Примечание о поддержке float64 на устройствах) sklearn.metrics.pairwise.laplacian_kernelsklearn.metrics.pairwise.linear_kernelsklearn.metrics.pairwise.manhattan_distancessklearn.metrics.pairwise.paired_cosine_distancessklearn.metrics.pairwise.paired_euclidean_distancessklearn.metrics.pairwise.paired_manhattan_distancessklearn.metrics.pairwise.pairwise_kernelssklearn.metrics.pairwise.polynomial_kernel-
sklearn.metrics.pairwise.rbf_kernel(см. Примечание о поддержке float64 на устройствах) sklearn.metrics.pairwise.sigmoid_kernelsklearn.metrics.precision_scoresklearn.metrics.precision_recall_curvesklearn.metrics.precision_recall_fscore_supportsklearn.metrics.r2_scoresklearn.metrics.recall_scoresklearn.metrics.roc_curvesklearn.metrics.root_mean_squared_errorsklearn.metrics.root_mean_squared_log_errorsklearn.metrics.zero_one_loss
13.2.4.4. Инструменты
13.2.5. Обработка типов входных и выходных массивов
Оцениватели и функции оценки могут принимать входные массивы из разных библиотек массивов и/или с разных устройств. Если передан набор входных массивов разных типов, scikit-learn при необходимости преобразует массивы, чтобы привести их к единому виду.
Для оценивателей действует правило «всё следует за X » — входные массивы разных типов преобразуются так, чтобы соответствовать библиотеке массивов и устройству X. Для функций оценки действует правило «всё следует за y_pred » — входные массивы разных типов преобразуются так, чтобы соответствовать библиотеке массивов и устройству y_pred.
Если функция или метод вызывается с входными данными, совместимыми с Array API, принято возвращать массивы из той же библиотеки массивов и на том же устройстве, что и входные данные.
13.2.5.1. Оцениватели
Если оцениватель обучается на данных X, совместимых с Array API, все остальные входные массивы, включая аргументы конструктора (например, y, sample_weight), будут преобразованы для соответствия библиотеке массивов и устройству X, если они ещё не соответствуют им. Это поведение позволяет в любой момент конвейера переключаться с вычислений на CPU на вычисления на GPU.
Благодаря этому оцениватели могут принимать входные данные разных типов, позволяя перемещать X на другое устройство в конвейере, не перемещая явно y. Обратите внимание, что конвейеры scikit-learn не допускают преобразования y (во избежание утечки данных).
Рассмотрим, например, конвейер, в котором X и y изначально находятся на CPU и проходят следующие три этапа:
-
TargetEncoder, преобразующий категориальныеXи требующий такжеy, поэтому иX, иyдолжны находиться на CPU. -
FunctionTransformer(func=partial(torch.asarray, device="cuda")), перемещающийXна GPU для повышения производительности на следующем этапе. -
Ridge, производительность которого можно повысить, передав ему массивы на GPU, поскольку он может очень эффективно выполнять операции с большими матрицами.
Изначально X содержит категориальные строковые данные (поэтому должен находиться на CPU); в TargetEncoder они преобразуются целевым кодированием в числовые значения. Затем X явно перемещается на GPU для повышения производительности Ridge. Конвейер не может преобразовать y (помните, что конвейеры scikit-learn не допускают преобразования y), но это не мешает выполнению конвейера, поскольку Ridge может принимать входные данные разных типов.
Обученные атрибуты оценивателя, обученного на данных X, совместимых с Array API, будут представлены массивами из той же библиотеки, что и входные данные, и сохранены на том же устройстве. Методы predict и transform впоследствии ожидают входные данные из той же библиотеки массивов и с того же устройства, что и данные, переданные методу fit.
13.2.5.2. Функции оценки
Если функции оценки переданы данные y_pred, совместимые с Array API, все остальные входные массивы (например, y_true, sample_weight) будут преобразованы для соответствия библиотеке массивов и устройству y_pred, если они ещё не соответствуют им. Благодаря этому функции оценки могут принимать входные данные разных типов и использоваться внутри метаоценивателя (или функции, принимающей оцениватели) с конвейером, перемещающим входные массивы между устройствами (например, с CPU на GPU).
Например, чтобы использовать описанный выше конвейер внутри, скажем, cross_validate или GridSearchCV, используемая внутри функция оценки должна уметь принимать входные данные разных типов.
Тип выходных данных функций оценки зависит от количества возвращаемых значений. Если функция оценки возвращает скалярное значение, она вернёт скаляр Python (обычно экземпляр float), а не скалярное значение массива. Функции оценки, поддерживающие многоклассовую классификацию или множественный вывод, вернут массив из той же библиотеки массивов и на том же устройстве, что и y_pred, если требуется вывести несколько значений.
13.2.6. Общие проверки оценивателей (для разработчиков)
Добавьте тег array_api_support в набор тегов оценивателя, чтобы указать, что он поддерживает Array API. Это включит специальные проверки в составе общих тестов, позволяющие убедиться, что результаты оценивателей одинаковы при использовании стандартного NumPy и входных данных Array API.
Для запуска этих проверок необходимо установить array-api-strict в тестовом окружении. Это позволяет запускать проверки без GPU. Для запуска проверок на настоящих GPU-устройствах также необходимо установить PyTorch, CuPy и/или dpnp, а также иметь совместимое оборудование GPU. Ожидается, что полный охват GPU будет распределён между несколькими машинами, поскольку для бэкендов CUDA, MPS и Intel GPU требуется разное оборудование. Проверки, которые невозможно выполнить или для которых отсутствуют зависимости, будут автоматически пропущены. Поэтому важно запускать тесты с флагом -v, чтобы видеть, какие проверки пропускаются:
pip install array-api-strict # and other libraries as needed pytest -k "array_api" -v
Запуск тестов scikit-learn на array-api-strict должен помочь выявить большинство проблем в коде, связанных с обработкой входных данных с нескольких устройств, за счёт использования имитируемых устройств, отличных от CPU. Это позволяет быстро выполнять итеративную разработку и отладку кода, связанного с Array API.
Однако для полной проверки обработки входных данных PyTorch, CuPy или dpnp, размещённых на реальных GPU-устройствах, необходимо запускать тесты с этими библиотеками и оборудованием. Это можно сделать с помощью Google Colab для CUDA или используя нашу инфраструктуру CI для pull request. Тесты для CUDA и Intel GPU запускаются сопровождающими вручную. Тестирование Intel GPU для PyTorch XPU и dpnp выполняется на выделенном собственном runner: probabl-ai/scikit-learn-intel-workflow.
13.2.7. Примечания
13.2.7.1. Примечание о поддержке устройств MPS
В macOS PyTorch может использовать Metal Performance Shaders (MPS) для доступа к аппаратным ускорителям (например, к встроенному графическому процессору чипов M1 или M2). Однако на момент написания документа поддержка устройств MPS в PyTorch реализована не полностью. Дополнительные сведения см. в следующей задаче на GitHub:
Чтобы включить поддержку MPS в PyTorch, задайте переменную окружения PYTORCH_ENABLE_MPS_FALLBACK=1 перед запуском тестов:
PYTORCH_ENABLE_MPS_FALLBACK=1 pytest -k "array_api" -v
На момент написания документа все тесты scikit-learn должны проходить, однако скорость вычислений не обязательно будет выше, чем при использовании CPU.
13.2.7.2. Примечание о поддержке устройств для float64
Некоторые операции в scikit-learn автоматически выполняются над числами с плавающей точкой с точностью float64, чтобы предотвращать переполнения и обеспечивать корректность (например, metrics.pairwise.euclidean_distances, preprocessing.StandardScaler). Однако некоторые сочетания пространств имён массивов и устройств, например PyTorch на MPS (см. Примечание о поддержке устройств MPS) и некоторые устройства Intel GPU с PyTorch XPU или dpnp, не поддерживают тип данных float64. В таких случаях scikit-learn переключается на тип данных float32. Это может привести к отличиям в поведении (обычно к численно нестабильным результатам) по сравнению с использованием диспетчеризации Array API или устройства с поддержкой float64.
13.2.7.3. Примечание о поддержке Intel GPU
Поддержка PyTorch XPU доступна только в PyTorch версии >= 2.12. Подробные сведения о совместимости и инструкции по настройке см. в документации PyTorch XPU.
© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/modules/array_api.html