Python 분산 처리 Spartan

이 기사는 파이썬으로 분산 처리하고 싶은 분을 향한 기사입니다.



파이썬의 이미지는 느리다는 분도 많다고 생각합니다.

그 이미지를 닦아내기 위해서 cython등의 라이브러리가 나와 있습니다만, 이번은 python을 고속화하는 수법의 하나로서 분산 처리에 대해 소개하려고 생각합니다.

분산 처리의 대표라고 하면.

· Hadoop
・Spark

입니다.

이번에는 Spark를 단순히 파이썬에 적용하고 싶습니다.
아래의 기사에서 JVM과 Python의 데이터 구조의 변환이 여러 번 일어나고, 대기 시간이 커지기 때문에 너무 빨라지지 않는다고 설명이있었습니다.



위 그림의 구조를 살펴보면 Spark Worker와 데이터를 파이프하는 부분이 많이 분산 처리하면 거기가 넥이 될지도 모른다는 인상을 받습니다.

스파르탄



그래서 이번에는 Python에서의 데이터 처리는 NumPy라는 행렬 데이터 구조를 사용하여 고속화할 수 있기 때문에 Numpy 행렬을 Spark의 RDD처럼 분산화하려는 시도의 Spartan이라는 프로젝트로 작성된 라이브러리를 사용해보기로 결정했습니다.

의존 라이브러리 관계에서 spython2 시스템이 아니면 잘 움직이지 않았습니다.
python3 시스템에 대한 대응이 바람직합니다.

python3 계의 사람은 virtualenv도 pyenv도 좋기 때문에 2 계의 환경으로 해주세요.

라이브러리 도입



그럼 환경 구축 절차입니다. (Mac에서만 시도하고 있습니다)
requirement.txt 를 아래와 같이 준비하고 pip install -r requirement.txt 로 설치합니다.
numpy
chainer==1.1.2
ipython==4.0.0
notebook==4.0.4
jinja2==2.8
pyzmq==14.7.0
tornado==4.1
scipy
dsltools
cython
parakeet
scikit-learn
traits
psutil

설치


git clone https://github.com/spartan-array/spartan.git
cd spartan
python setup.py develop

위에서 설치 완료입니다.

그러나 Mac이라고 사용하려면 추가 설정이 필요했습니다.
spartan/worker.py

위의 파이썬 파일을 변경해야합니다.

기본 상태라면
psutil.TOTAL_PHYMEM
psutil.NUM_CPUS

2 개가 설정되지 않고 오류가 발생하기 때문에,
    ret = psutil.virtual_memory()
    num_cpus = psutil.cpu_percent()
    psutil.TOTAL_PHYMEM = ret.total
    psutil.NUM_CPUS = num_cpus

위를 아래의 프로그램 행 앞에 추가하여 설정이 가능합니다. 설정하고 있는 것은 가상 메모리와 CPU를 얼마나 사용하는지를 설정하고 있습니다.
psutil은 메모리나 CPU의 사용을 조정, 관리할 수 있는 프로그램이므로 자세하게 알고 싶은 분은 아래를 봐 주세요.

또 환경설정에서 싱글 밖에 사용하지 않는 설정을 하고 있는 경우는 아래의 사이트로부터 설정해 주세요.
    self.worker_status = core.WorkerStatus(psutil.TOTAL_PHYMEM, 
                                           psutil.NUM_CPUS,
                                           psutil.virtual_memory().percent,
                                           psutil.cpu_percent(),
                                           time.time(),
                                           [], [])

그럼 실제로 동작시켜 봅시다.

이름을 lreg.py로 다음과 같은 선형 회귀 프로그램을 작성합니다.
import spartan as sp
sp.initialize()

N_DIM = 10
N_EXAMPLES = 1000 * 1000
EPSILON = 1e-6

x = 100 * sp.ones((N_EXAMPLES, N_DIM)) + sp.rand(N_EXAMPLES, N_DIM)
y = sp.ones((N_EXAMPLES, 1))

# put weights on one server
w = sp.rand(N_DIM, 1)

for i in range(50):
    yp = sp.dot(x, w)
    diff = x * (yp - y)
    grad = sp.sum(diff, axis=0).reshape((N_DIM, 1))
    w = w - (grad / N_EXAMPLES * EPSILON)
    print grad.sum().glom()

아래의 명령으로 동작시킵니다.
python lreg.py --log_level=WARN

실행하면 풀로 CPU와 메모리를 먹기 때문에 굳어집니다.
PC에 스파르타인 것을 강요하면 좋지 않네요.

이번은 본질적인 클러스터로 동작시키는 곳까지 가고 있지 않으므로, 향후, 시험해 갈 예정입니다.

이용은 계획적으로! !

이번 리포지토리는 이쪽

참고 자료

좋은 웹페이지 즐겨찾기