Статьи
August 12

pip vs conda: сравнение двух пакетных менеджеров

Если вы используете Python для задач в области data science, то, вероятно, знакомы с двумя популярными пакетными менеджерами: pip и conda. Но, возможно, у вас возникали вопросы:

  • Чем они отличаются друг от друга?
  • Какие у них достоинства и недостатки?
  • Какой лучше использовать?

По итогу вы узнаете, зачем вообще придумали Conda, и когда его стоит использовать.

Что-то кроме Python?

Основное различие между pip и conda заключается в том, какие пакеты, модули и библиотеки они поддерживают..

  • pip содержит разнообразные библиотеки для Python.
  • conda, в свою очередь, включает в себя библиотеки Python, библиотеки на языке C, различные компиляторы и интерпретаторы.

pip: только для Python

Предположим, что вы хотите установить сам Python, numpy, pandas и инструмент рендеринга gnuplot, не связанный с Python. Вот как будет выглядеть файл зависимостей для pip (без версий):

numpy
pandas

Установка самого Python и gnuplot выходит за рамки pip. Можно, например, использовать Docker:

FROM ubuntu:20.04
RUN apt-get update && apt-get install -y gnuplot python3.9
COPY requirements.txt .
RUN pip install -r requirements.txt

Интерпретатор Python, и gnuplot мы получаем из системного пакетного менеджера, в данном случае Ubuntu.

conda: может содержать почти любую зависимость

С conda, Python и gnuplot — это просто дополнительные пакеты Conda, ничем не отличающиеся от numpy или pandas. Файл environment.yml, который соответствует (в некоторой степени) файлу requirements.txt, будет включать все эти пакеты:

name: myenv
channels:
  - conda-forge
dependencies:
  - python=3.9
  - numpy
  - pandas
  - gnuplot

Conda использует операционную систему только для выполнения основных функций, таких как работа со стандартной библиотекой C. Всё остальное, что нужно для работы, — это пакеты Conda, а не системные пакеты.

Мы можем заметить разницу: если соответствующий файл Dockerfile не требует установки каких-либо системных пакетов:

FROM continuumio/miniconda3
COPY environment.yml .
RUN conda env create

В этом случае базовый образ уже содержит предустановленную Conda, но мы не используем какую-либо существующую установку Python. Вместо этого мы устанавливаем новую среду с нуля.

Почему conda поставляет всё сразу

Почему conda решила упаковать всё, включая интерпретатор Python?

Это решение приносит несколько преимуществ.

  • Во-первых, оно обеспечивает переносимость между операционными системами. Вместо того чтобы устанавливать Python тремя разными способами в Linux, macOS и Windows, вы можете использовать один и тот же файл environment.yml во всех трёх операционных системах.
  • Во-вторых, это решение обеспечивает воспроизводимость. Вы можете закрепить почти весь стек, начиная с интерпретатора Python и выше.
  • В-третьих, это решение позволяет иметь согласованную конфигурацию. Вам не нужно устанавливать системные пакеты и пакеты Python двумя разными способами, всё может быть помещено в один файл environment.yml.

Но это также решает другую проблему: как работать с библиотеками Python, для которых требуется скомпилированный код? Это достаточно большая тема, и мы рассмотрим её в следующем разделе.

Помимо чистого Python: упаковка скомпилированных расширений

На начальном этапе разработки Python package содержал только исходный код, который нужно было установить. Для простых пакетов на Python это работало хорошо и работает до сих пор.

Однако как быть, если вам нужно скомпилировать код на Rust, C, C++ или Fortran в процессе сборки пакета?

Решение №1: скомпилируйте его самостоятельно

Изначально предполагалось, что каждый пользователь будет самостоятельно компилировать код во время установки. Этот процесс может быть довольно медленным и ресурсоёмким, а также часто вызывает сложности в настройке. Кроме того, он не решает основную проблему — зависимости от разделяемых библиотек.

Например, графическая библиотека изображений Pillow использует сторонние разделяемые библиотеки, такие как libpng и libjpeg. Чтобы скомпилировать Pillow самостоятельно, необходимо установить все эти библиотеки, а также соответствующие заголовочные файлы для разработки.

В Linux или macOS можно воспользоваться системными пакетами или пакетами Homebrew для установки библиотек. В Windows это может быть сложнее. Однако даже в этом случае придётся создавать различные конфигурации для каждой операционной системы и даже для разных дистрибутивов Linux.

Решение №2: pip wheel

pip решает эту проблему с помощью специальных пакетов, называемых «wheel». Эти пакеты могут содержать скомпилированный код.

Чтобы работать с зависимостями разделяемых библиотек, таких как libpng, все внешние зависимости объединяются внутри самого пакета wheel.

Давайте рассмотрим пример: колесо Pillow для Linux. Wheel — это просто ZIP-файл, поэтому мы можем использовать инструменты для работы с ZIP-файлами:

$ zipinfo Pillow.whl
...
Pillow.libs/libpng16-213e245f.so.16.37.0
Pillow.libs/libjpeg-183418da.so.9.4.0
...
PIL/FpxImagePlugin.py
PIL/PalmImagePlugin.py
...
PIL/_imagingcms.cpython-39-x86_64-linux-gnu.so
...

Как видно из списка, wheel включает в себя не только код Python и скомпилированное расширение Python, но и сторонние разделяемые библиотеки, такие как libpng и libjpeg. Это может привести к увеличению размера пакетов, поскольку для каждого колеса устанавливается несколько копий сторонних библиотек.

Решение №3: пакеты Conda

Пакеты conda используют другой подход к сторонним разделяемым библиотекам. libjpeg и libpng упакованы как дополнительные пакеты Conda:

$ conda install -c conda-forge pillow
...
The following NEW packages will be INSTALLED:

...
  jpeg               conda-forge/linux-64::jpeg-9d-h36c2ea0_0
...
  libpng             conda-forge/linux-64::libpng-1.6.37-h21135ba_2
...
  pillow             conda-forge/linux-64::pillow-7.2.0-py38h9776b28_2
  zstd               conda-forge/linux-64::zstd-1.5.0-ha95c52a_0
...

Кроме того, от установленных библиотек libjpeg и libpng могут зависеть и другие установленные пакеты. Эти библиотеки не привязаны к конкретному пакету и доступны для любого пакета в среде conda.

conda способна на это, поскольку является не только системой управления пакетами для кода на Python. Она также может легко упаковывать общие библиотеки и исполняемые файлы.

Резюме: pip против conda

PyPI против Conda-Forge

Еще одно фундаментальное различие между pip и conda заключается не столько в самих инструментах, сколько в репозиториях пакетов, на которые они полагаются, и в том, как они работают. В частности, большинство программ на Python будут полагаться на библиотеки с открытым исходным кодом, и их нужно откуда-то загружать. Для этого pip полагается на PyPI, в то время как conda поддерживает несколько различных "каналов", размещенных на Anaconda.

Канал conda по умолчанию поддерживается компанией Anaconda Inc, которая создала conda. Он обычно имеет ограниченный выбор пакетов, но зато более стабилен и лучше поддерживает работу с графическим процессором.

Но есть также канал сообщества Conda-Forge, который содержит гораздо больше пакетов, и именно оттуда вы, вероятно, чаще всего будете загружать пакеты conda. При этом вы можете использовать пакеты из обоих каналов одновременно.

Давайте сравним PyPI с Conda-Forge.

PyPI

Обычно пакеты на PyPI загружает автор пакета Python.

Каждый сопровождающий пакета может создавать свои пакеты по-своему. Они могут поддерживать собственную инфраструктуру сборки, выбирать свои собственные параметры компиляции и так далее.

Например, NumPy может полагаться на несколько различных библиотек BLAS для быстрых операций с линейной алгеброй. Разработчики NumPy решили создавать свои пакеты PyPI с помощью OpenBLAS. Если вам нужен другой вариант, например, более быстрый MKL от Intel, вам не повезло, если вы не хотите компилировать код самостоятельно.

Conda-Forge

Conda-Forge — проект, созданный сообществом, в котором сопровождающие пакета могут отличаться от первоначального автора пакета.

Вместо того чтобы полагаться на разные пользовательские сборки, выполняемые каждым сопровождающим пакета по-своему, Conda-Forge использует централизованные системы сборки. Эти системы перекомпилируют библиотеки, обновляют репозитории рецептов и в целом автоматизируют все процессы. Например, когда выходит новая версия Python 3, происходит централизованное обновление, и все отдельные сопровождающие пакеты получают PR с новыми версиями. В случае с PyPI это зависит от действий отдельных сопровождающих.

Работа с пакетами только для PyPI в Conda

Хотя Conda-Forge содержит множество пакетов, он не включает в себя все из них. Многие пакеты Python можно найти только на PyPI. Если вам не хватает каких-либо пакетов, есть несколько способов решить эту проблему.

Установка пакетов pip в среде Conda

Среды conda — это оболочки вокруг virtualenvs; поэтому вы можете просто вызвать pip install самостоятельно. Если вы используете environment.yml для установки пакетов conda, вы также можете добавить пакеты pip:

name: myenv
channels:
  - conda-forge
dependencies:
  - python=3.9
  - numpy
  - pandas
  - gnuplot
  - pip:
      # Пакет, присутствующий только в PyPI
      - sandu

Самостоятельная упаковка пакета для Conda-Forge

Поскольку Conda-Forge не требует от сопровождающих кода выполнения упаковки, любой желающий может самостоятельно добавить пакет в Conda-Forge.

Для многих пакетов Python этот процесс является удивительно простым и хорошо автоматизированным. Поэтому обработка новых выпусков зачастую сводится к утверждению автоматически созданного PR.

Резюме: PyPI против Conda-Forge

Дополнительный инструментарий для pip и conda

Вот краткий обзор некоторых дополнительных инструментов, которые могут быть полезны при работе с любой из систем:

Итак, что же лучше использовать: pip или Conda?

Для базовой работы в Python обычно достаточно pip и PyPI.

Однако если вы занимаетесь data science, то способность conda упаковывать библиотеки сторонних разработчиков и централизованная инфраструктура, предоставляемая Conda-Forge, могут значительно упростить настройку сложных пакетов.

В конечном счёте, выбор будет зависеть от вашей ситуации и требований. Вполне возможно, что вам подойдут оба инструмента.

Источник: Python Speed

👉🏻Подписывайтесь на PythonTalk в Telegram 👈🏻

👨🏻‍💻Чат PythonTalk в Telegram💬

🍩 Поддержать канал 🫶