Python 환경의 의존성, 설치와 시작 오류
Code Repository의 Checks 로그에서 먼저 실패한 task와 원인을 확인합니다. 현재 환경 해석은 Hawk를 사용하지만 이전 또는 해당 실행 경로의 Mamba 메시지도 볼 수 있습니다. 버전 충돌, 아티팩트 접근 실패와 실제 변환 실행 오류를 구분해야 합니다.
직접 및 전이 의존성
패키지 A가 B와 C를, C가 D를 요구하면 D는 A의 전이 의존성입니다. A를 요청하는 것만으로 D의 버전에도 조건이 생깁니다.
실제 예로 statsmodels는 NumPy, SciPy와 Matplotlib을 요구할 수 있고, Matplotlib의 libpng, setuptools, cycler, dateutil과 kiwisolver도 환경에 들어옵니다. 직접 추가하지 않은 패키지가 충돌 원인일 수 있습니다.
트리형 Mamba 메시지
Mamba의 트리 형태 오류는 2023년 2월 이후 Foundry의 관련 실행 경로에서 제공됩니다. 다음 문구로 충돌 위치를 읽습니다.
| 문구 | 의미와 대응 |
|---|---|
The following packages are incompatible | 전체 요구의 버전 충돌입니다. 아래의 의존 경로를 읽습니다. |
The following package could not be installed | 설치할 수 없는 패키지가 있습니다. 이어지는 원인을 확인합니다. |
can be installed | 이 후보만 보면 설치할 수 있다는 뜻입니다. 다른 요구와 동시에 가능한지는 뒤의 충돌을 봐야 합니다. |
no viable options | 다른 제약과 동시에 맞는 후보가 없습니다. 후보 범위를 배제한 요구를 완화합니다. |
does not exist, perhaps a (typo or a) missing channel | 패키지 이름, 버전과 채널을 확인합니다. |
is installable and it requires | 설치 가능한 후보가 추가 의존성을 요구합니다. |
is uninstallable because it requires | 아래 의존성의 충돌 때문에 이 후보를 설치할 수 없습니다. |
is installable with the potential options | 여러 후보 중 하나를 고를 수 있으며 각 후보에 별도 조건이 있습니다. |
conflicts with any installable versions previously reported | 앞에서 설치 가능하다고 가정한 버전과 충돌합니다. 같은 패키지의 직접 및 전이 요구를 대조합니다. |
is missing on the system | 시스템의 virtual package가 없습니다. 예를 들어 CUDA 패키지가 요구한 __cuda 조건을 현재 시스템이 제공하지 못할 수 있습니다. |
which cannot be installed (as previously explained) | 앞서 설명한 충돌이나 같은 의존 조건을 다시 참조합니다. |
충돌 유형의 예
| 유형 | 진단 예 |
|---|---|
| 직접 충돌 | 같은 환경에 python 3.7.*과 python 3.8.*을 함께 요구하면 두 버전을 동시에 설치할 수 없습니다. |
| 직접 의존성 충돌 | NumPy 1.22.0은 Python 3.8 이상을 요구하므로 Python 3.7.*과 맞지 않습니다. 해당 빌드의 Python 3.8, 3.9, 3.10 및 python_abi 후보를 비교합니다. |
| 전이 의존성 충돌 | huggingface-adapter 0.1.1*이 palantir_models를 통해 pyspark-src >=3.2.1,<3.3.0a0를 요구하고, transforms 1.645.0이 pyspark-src 3.2.1_palantir.36을 요구하는 식의 충돌입니다. 직접 추가한 두 패키지의 제약을 함께 조정해야 합니다. |
위 버전들은 과거 오류를 해석하는 사례이며 현재 설치 권장 목록이 아닙니다. 실제 Python은 지원 일정을 따릅니다.
Python과 python_abi는 연동된 요구로 보고 Python 버전을 조정합니다. ABI만 임의로 지정하여 충돌을 숨기지 않습니다. pthon 3.8.* 같은 이름 오타나 존재하지 않는 python 3.423.*도 missing channel과 비슷한 메시지를 낼 수 있습니다.
Legacy Mamba 메시지
패키지를 찾지 못함
Problem: nothing provides requested A.a.a.a
어느 구성 채널도 A의 요청 버전을 제공하지 않습니다. pin을 완화하거나 실제 제공되는 패키지 및 버전을 확인합니다. External repository에서는 Conda label을 지원하지 않으므로 label에만 있는 패키지를 일반 저장소에서 찾을 수 있다고 가정하지 않습니다.
의존 패키지를 찾지 못함
Problem: nothing provides B-b.b.b needed by A-a.a.a:
A가 요구하는 B가 없거나 회수되었을 수 있습니다. B는 직접 요구 또는 전이 의존성일 수 있습니다. 다른 A 버전이 호환되는 의존성을 쓰는지 확인하고, 필요한 패키지가 인스턴스에 없다면 제공을 요청합니다.
중복 버전
cannot install both X.a.b.c and X.d.e.f
같은 패키지의 서로 다른 버전을 동시에 고정한 경우입니다. 중복 요구를 제거하고 최종 의존성 집합을 다시 해석합니다.
권한
CondaService:ReadRepositoryPermissionDenied
필요한 자산과 패키지가 해당 인스턴스에 있는지, 참조 및 읽기 권한이 있는지 확인합니다. 가용성을 복구한 뒤 해당 실행 구성을 다시 반영해야 합니다.
의존성 범위 충돌
Problem: package A-a.a.a requires B >=2.2.5,<2.3.0a0, but none of the providers can be installed
B를 직접 선언하지 않았더라도 다른 의존성이 같은 B의 호환되지 않는 버전을 요구할 수 있습니다.
충돌을 좁히는 절차
패키지를 줄여 성공하는 최소 구성을 찾고 하나씩 다시 추가합니다. pin을 풀어 후보가 생기는지도 비교합니다. 여러 저장소나 브랜치 또는 Workbook 프로필에서 제약을 절반씩 나누어 확인하면 큰 의존 집합의 원인을 좁히기 쉽습니다.
Workbook에서 자동 선택이 너무 오래된 Pandas, Matplotlib이나 NumPy로 향한다면 Environment > Customize Spark environment > Customize Profile에서 필요한 지원 버전을 고릅니다.
과거 프로필에는 pandas=0, matplotlib=2, numpy<1.20 같은 기본 요구가 있어 새 패키지와 충돌할 수 있습니다. 모든 현재 프로필의 고정 기본값으로 단정하지 말고 실제 요청 및 해석 결과를 확인합니다.
상세 solver 로그
CI 로그의 Execution failed for task ':transforms-python:<task-name>'에서 실패 task를 찾습니다. Mamba 기반의 해당 task가 condaPackRun이면 Python 하위 프로젝트 build.gradle에 상세 인자를 추가하여 조사할 수 있습니다.
tasks.condaPackRun {
additionalArguments "-vvv"
}
상세 로그는 checks를 느리게 할 수 있습니다. 실제 task와 사용하는 solver의 옵션을 확인하며 이 Mamba 인자를 모든 Hawk 명령의 공통 옵션으로 가정하지 않습니다.
Pin을 풀어도 해결되지 않음
모든 패키지가 제공되더라도 서로 호환되는 조합이 없을 수 있습니다. 패키지가 없거나 회수되었는지, 새 버전이 깨졌는지, Python 버전과 맞지 않는지를 구분합니다.
성공한 checks와 실패한 checks의 잠금 파일을 비교합니다. 숨김 파일을 켜서 transforms-python/conda-versions.run.linux-64.lock의 바뀐 패키지 버전을 찾고 필요한 버전 제약을 meta.yaml에 반영합니다.
요청을 바꾸지 않았는데 실패
공개 채널의 상위 패키지 변화가 영향을 줄 수 있습니다. 업그레이드 PR도 새 의존성을 도입하고 환경 재해석을 일으킬 수 있습니다. 성공 및 실패 commit의 의존성 및 업그레이드 차이를 확인합니다.
업그레이드 commit을 되돌려 비교할 때도 코드 검토와 실제 파일 변경 범위를 유지해야 합니다. 원인을 확인한 뒤 충돌을 해결하여 업그레이드를 다시 적용합니다.
요청은 같지만 checks가 느림
저장소를 최신 템플릿으로 갱신하고, 모듈을 import할 때 실행하는 최상위 코드가 추가되었는지 봅니다. 자동 변환 발견은 모듈들을 import하므로 그 코드도 checks의 시간에 영향을 줍니다.
Meta.yaml 변경 뒤 timeout 또는 OOM
환경을 구성하는 단계에서 발생했다면 해석 불가능한 패키지 조합과 solver 메모리를 확인합니다. 이미 변환 계산이 시작된 뒤의 OOM은 실제 데이터 및 자원 사용도 조사해야 합니다. 모든 메모리 오류를 패키지 버전 문제로 처리하지 않습니다.
빌드의 Conda 설정 실패
CondaEnvironmentSetupError
Driver 로그에서 실제 오류를 확인합니다. Job comparison으로 성공 및 실패 빌드의 코드와 meta.yaml 차이를 봅니다. 설정 변경을 되돌려 해결되는지 확인한 뒤 해당 의존성 충돌을 좁힙니다.
코드와 요청이 같다면 Infra details > Environment > SparkModuleVersion에서 모듈 버전을 비교합니다. 런타임 변경이 원인이라면 Palantir 담당자와 이전 버전 또는 지원되는 수정 경로를 확인합니다.
여러 아티팩트 다운로드 실패
RuntimeError: Multi-download failed
채널에 접근할 권한이 없거나 아티팩트가 인스턴스에 없을 수 있습니다. 실제 원인은 driver 로그에서 확인합니다.
저장소 템플릿을 구성하며 채널 목록에 경고가 나타난다면 잘못된 참조와 권한을 확인합니다. 잘못된 채널을 제거해야 하는 경우 관리 권한을 확보하고, 이후 checks와 빌드를 다시 시작합니다. 필요한 패키지를 제공하는 정상 채널까지 무작정 지우지 않습니다.
Pipeline entry point 오류
transforms._errors.EntryPointError: "Key {name} was not found, please check your repo's meta.yaml and setup.py files"
빌드에 필요한 루트 메타데이터가 빠졌을 수 있습니다. Dataset Preview는 가능해도 빌드가 실패할 수 있습니다.
새 Python 저장소의 기본 파일이나 프로젝트 구조를 기준으로 meta.yaml과 setup.py의 필요한 정보를 확인합니다. 누락을 보완하고 commit한 뒤 checks가 성공하면 빌드를 다시 실행합니다.
Python 패키지와 JAR를 함께 구성
GraphFrames는 Python API와 Java 구현 JAR가 모두 필요한 예입니다. Conda 패키지만 추가하면 다음과 같은 오류가 날 수 있습니다.
o257.loadClass.: java.lang.ClassNotFoundException:<Class>
Java classpath reference error와 함께 JAR 의존성을 추가하라는 메시지가 나타날 수도 있습니다.
- Libraries에서 Python 패키지를 추가합니다.
- 숨김 파일을 표시하고 Python 하위 프로젝트의 build.gradle에 호환되는 JAR를 condaJars 의존성으로 추가합니다.
- 단위 테스트에도 필요하면 testing plugin을 먼저 적용하고 sparkJars에도 추가합니다.
Spark-NLP 5.0.2를 사용하는 Scala 2.12 환경의 예는 다음과 같습니다. 실제 설치한 패키지와 JVM 측 아티팩트의 버전 및 Scala 대상이 맞아야 합니다.
apply plugin: 'com.palantir.transforms.lang.pytest-defaults'
dependencies {
condaJars 'com.johnsnowlabs.nlp:spark-nlp_2.12:5.0.2'
sparkJars 'com.johnsnowlabs.nlp:spark-nlp_2.12:5.0.2'
}
테스트에 사용하지 않는 JAR라면 condaJars만 구성할 수 있습니다. 좌표 형식은 group:name:version이며 해당 라이브러리의 호환 버전을 선택합니다.
버전 관리 원칙
Python은 지원하는 major.minor 범위로 관리하고 명시적으로 고정하면 build와 run을 같게 둡니다. 지원하지 않는 Python 범위식은 피합니다. 이전 구성에서 잘못된 조건이 Python 3.6.* 같은 종료 버전으로 이어질 수 있으므로 실제 해석 결과를 확인해야 합니다.
다른 패키지는 필요 이상으로 모두 pin하지 않습니다. 성능이나 호환성 때문에 pin했다면 중요한 업데이트가 막히지 않도록 유지 관리합니다.
Workbook의 버전은 프로필에서 Automatic과 필요한 명시 버전을 선택하여 관리합니다.
해결되지 않는 문제는 전체 오류 로그, 변경한 환경과 수행한 조사를 포함하여 Palantir 지원팀에 요청합니다.