TechY's blog
Always think Tech and Y

Apache Spark를 알아보자

|

Data engineer 가 되기 위해 필요한 기술 스택들을 하나씩 알아보다보니, Spark라는 processing framework이 많이 나오는 것 같아서, 한번 가볍게 훑어보기로 했다. 해당 포스트는 정리와 메모 용도이기 때문에, 오역이 있을 수 있어, 계속적인 수정과 추가가 될 예정이다.

참고 자료 :

우선 distributed system이 무엇인지에 대해서 간략하게 알아본다.

mutiple entities talking to one another in some way, while also perfomring their own operations

다수의 entity가 있고, 이들이 서로 “상호작용” 하면서 각자의 “연산”을 하는 것을 distributed system라고 한다. 여기서 entity는 우리의 관심 아래에서는 process 가 될 수 있겠다. entity를 일반화하고 공식화하기 위해서 이를 그래프 이론에 있는 node, edge 로 치환하여 {entity:node, communication:edge} 로 사용한다.

큰 부하가 요구되는 operation이 여러 가지의 node로 나뉘어지고, operation 자체의 속도나 양은 줄게 된다.

하지만, single system에는 존재하지 않았던 node 간 communication 시간이 발생하면서 bottleneck으로 작용할 수 있게 된다. 또한, 발생 가능한 문제로써, sequence가 중요한 경우, 각 node들의 분리된 연산이 끝나고 join 되는 과정에서 distributed system 자체의 clock를 쓴다고 하는데, 이 방법이 완전 무결한 것은 아니라고 한다.

Spark 운영 방식 중 분산 처리 부분을 알아보자.

  • Partitioned data

데이터를 하나가 아닌 여러 개의 노드로 나누기 위해서는 데이터 또한 나뉘어져야 한다. 쉽게 생각해서, 판다스 데이터 프레임이 종 또는 횡으로 파티션 되는 것을 생각해볼 수 있다.

  • Fault Tolerance

분산 처리에서 노드들은 서로 communication하면서 연산이 진행되는데, 갑자기 한 노드가 에러가 나면서 작업이 실패하게 되어도 계속해서 프로그램을 진행하는 것을 의미한다. 이는 Spark 의 RDD 를 통해 구현된다 고 하는데, 이는 뒤에서 더 알아본다.

  • Lazy Evaluation

Spark의 분산 처리는 lazy evaluation을 진행하게 되는데, 여기서 evaluation은 각각의 코드 라인들이 어떤 것을 의미하고 어떤 결과를 낳는지에 대한 것이다. lazy evaluation이란, evaluation의 시점이 code expression의 결과값이 나오고 나서, 이를 추적함으로써, 컴파일 과정을 평가하는 것인데, 이는 유의미하고 실질적인 평가만을 보장하므로써, 프로그램을 더욱 효율적으로 만든다고 한다.

다음으로는 Spark 의 구성 요소들에 대해서 알아본다.

  • RDD (Resilient Distributed Datsets)

이는 Spark의 주요 데이터 구조로써, 불변한 성질을 가지고 있으며 파티션된 컬렉션(tuple, objects) 들의 기록라고 한다. 이러한 기록들은 분산 시스템으로 올라가 연산이 진행된다. RDD 데이터셋의 특징 중 하나는 스키마가 없다는 것인데, 쉽게 말해 컬럼이 없다. 따라서 형태가 리스트처럼 보이게 된다. 이에 따라, 다른 데이터셋보다 상대적으로 가독성이 떨어진다.

  • Spark DataFrames

RDD 의 특성을 다 가지고 있는 데이터셋이다. 똑같이 불변한 성질을 가지고 있다. 다만 스키마가 존재한다. 즉, RDD가 pd.Series 였다면, Spark DataFrame 은 pd.DataFrame 과 같은 성질을 가진다. (그래도 데이터 프레임과는 다른 성질을 띄고 있다.) 이에 따라, 더 높은 수준의 추상화를 지원하게 된다. ex) PySpark

  • Spark DataSets

static data type을 가지고 있는 Spark DataFrame으로, 자연스레 성능의 우위를 가지고 있지만, dynamic dtype을 지원하는 파이썬에서는 사용할 수 없다.

  • Transformation

특정 함수(연산)를 RDD에 적용을 하면, RDD는 불변하기 때문에, 새로운 RDD를 결과값으로 뱉게 된다.
어떤 tranformation 을 사용하느냐에 따라, narrow 와 wide가 나뉘어지게 되고, 이 기준은 파티션 데이터가 하나(single parent RDD)가 쓰이냐 아니면 다수(multiple partitions of RDD)가 쓰이냐에 있다. 이렇게 변환되어 나온 자식 RDD는 RDD lineage 라는 것에 올라간다. (다음에 다룬다.)

Alt text

Alt text

  • Actions

이전에 나온 Transformation은 “데이터 + 연산 = 변환된 데이터” 의 양상이었다. Actions의 경우 “데이터 + 연산 = 값” 의 형태로 여기서 “값” 은 데이터의 변형이 아닌, 의미를 가진 value가 된다. 예로 들어, 문장 내에 ‘안녕’ 이 몇 개가 있나 와 같은 것을 의미한다. 따라서, Actions의 경우 입력으로 RDD를 받지만 결과값으로 RDD를 가지지는 않는다.

  • Lineage Graph

Transformation 또는 Actions은 Graph를 생성하게 된다. 이는 logical execution plan이라고 불리기도 하는데, 컴파일러에게 어떤 RDD부터 컴파일을 시작할지에 대한 정보를 주는 그래프를 의미한다. 이 그래프는 Spark 의 특성 중 하나인 fault tolerance 와 관련이 있는데, 한 노드가 에러가 나면, 노드가 기존에 해야했어야 할 것으로 추정되는 정보가 lineage graph에 다른 곳으로 카피되어 저장된다.

Further works

  • 스파크를 실제로 써보자
  • 스파크를 공부하다보니, MapReduce 라는 참고 문헌과 같은 기술이 존재한다. 이를 공부해보자.
Comment  Read more

AWS 리눅스 서버 세팅 일기 (1)

|

이전 포스트에서 야심차게, Toy-project 를 하는 팀원들이 사용하는 로컬 컴퓨터끼리를 연결해주는 NAS 를 AWS 서비스를 통해 구현해보겠다는 계획이 있었으나, 회사의 동료의 조언에 따라, EC2 instance 를 하나 만들고, EBS를 장착하기로 하였다. 그에 따른 과정을 정리해보려 한다.


  1. EC2 instance 선택
  2. Linux 사용자 계정 생성
  3. 환경 설정

EC2 instance 선택

어떠한 EC2 instance 를 써야, CPU 와 Memory 측면에서 불편함 없이 사용할 수 있으며, 비용을 최소화할 수 있을지에 대한 고민이다. 요구 조건은 간략하게 아래와 같았다.

  • 3명 정도가 작업할 서버 (작업 시간은 보수적으로 같다고 설정)
  • 데이터 수집을 하게 된 후, 분석을 어느정도 할 수 있는 서버
  • 데이터의 양이 그리 크지는 않지만, 팀원들의 분석 과정이 memory-inefficient 할 것으로 간주

이에 따라, 후보군은 3가지 정도가 나왔다. 후보군은 링크 를 참고하였다.

  • r5.xlarge
    • vCPU : 4
    • Memory : 32
  • t3.xlarge
    • vCPU : 4
    • Memory : 16
  • t3.2xlarge
    • vCPU : 8
    • Memory : 32

후에 AWS Pricing Calculator를 사용해서, 1달 요금을 보니,

  • r5.xlarge
    • 119.07 USD
    • 작성 시점 147,266.37 원
  • t3.xlarge
    • 79.14 USD
    • 작성 시점 97,880.75 원
  • t3.2xlarge
    • 155.28 USD
    • 작성 시점 192,051.08 원

비싸다.. 그래도 이 계산기는 하루에 24시간 stop 없이 full 로 돌리는 것을 가정하니, 팀원들이 모두 대학생인 것을 감안하면, 14시부터 02시로 설정해서 완벽하게 인스턴스 스케줄링이 된다는 가정 하에, 위의 결과에서 절반정도가 들게 된다. 팀원이 3명이니까,

  • r5.xlarge
    • 24,544 원
  • t3.xlarge
    • 16,313 원
  • t3.2xlare
    • 32,000 원

그래도 대학생들에게 비싸긴 하다… 사실 여기서 그만 두고 싶었다.. 하지만 한번 끝까지 가보려 한다.

Linux 사용자 계정 생성

좋은 참고 자료가 있어, 아주 쉽게 해결되었다.

나, 팀원1/2 총 3명의 계정을 등록하고, home 폴더까지 셋팅이 끝났다.

환경 설정

데이터 분석을 위한 이런 저런 설정이 많지만, 가장 기본적으로 pip virtualenv 를 사용하였다. 설치한 패키지는 현재 내가 사용하고 있는, virtualenv 의 패키지를 그대로 넣어두었다.

Comment  Read more

EBS, EFS, S3 간략 정리

|

개인적 사이드 프로젝트로 한국 주식시장에 대한 Screener 및 Dashboard 사이드 프로젝트를 하게 되었다.

실습 겸 하여 AWS free tier를 사용해, 서버를 구축해보려고 하던 중에, 제일 먼저 저장한 데이터에 대한 처리 및 저장, 공유에 대해 고민하게 되었고, EBS(Elastic Block Store), EFS(Elastic File System), S3(Simple Storage Service) 를 이야기해보려 한다.

참고 자료 : AWS doc, redhat 사실 상 정리가 더 잘되어 있는 블로그

Alt text

  • 참고 자료의 이미지로, 위의 사진이 많은 것을 설명해주어 첨부하였다.

Amazon EBS

  • Block-level storage
  • EC2 에 붙여서(attach) 쓰는 storage 로써, 단일 EC2에만 attach할 수 있다.
  • EBS 볼륨은 EC2 인스턴스가 stop, terminate 되어도 독립적으로 유지된다. (외장 하드 느낌)
  • EBS snapshot을 지원한다.

Amazon EC2 instance store

  • EC2를 만들면 기본적으로 존재하는 스토리지이다.
  • 해당 볼륨은 EC2에 의존적이므로 인스턴스 수명과 볼륨의 수명이 일치한다.

Example of EBS & EC2 instance storage

Alt text

위의 이미지를 보면, EC2 instance를 생성할 때 설정했는 8G 의 용량이 disk라는 이름으로 할당되어 있고, xvdf 라는 이름으로 attach 된 EBS 볼륨이 /data 라는 path로 마운트되어 있다.

Amazon EFS file system

  • Scalable file storage
  • NAS 처럼 여러개의 EC2 인스턴스가 파일 시스템에 접근할 수 잇다. (공통 데이터 소스)
  • 기본적으로 제공되는 snapshot, backup 서비스가 없어서, 별다른 solution이나, AWS backup 서비스를 사용해야 한다.

Amazon S3

  • Object storage
  • 인터넷 데이터의 repository 역할을 한다. (get, post 등이 가능)
  • EC2 는 AMI(ex. os, app config) 를 저장하기 위해 S3를 사용
  • EBS, EC2 storage 의 snapshot, backup을 저장할 때 사용

무엇을 써야 할까

  • 상황
    • 여러 유저들의 작업은 각자 컴퓨터 로컬에서 이루어진다.
    • 데이터 소스는 NAS와 같이 네트워크로 연결된 형태여야 한다.
  • 생각의 흐름
    • S3는 wget, get과 같이 저장된 데이터를 commit, push 하는 형태이기 때문에, 실시간 sync가 되지 않아, NAS 대체로 적합하지 않다.
    • EC2를 사용하지 않을 것이기 때문에, EC2 attached storage 인 EBS는 사용할 수 없다. 심지어, EC2를 쓴다해도, 단일 EC2가 아닐 것이다.
    • EFS를 local server 에 마운트하면 가능하지 않을까

자료를 모아보자

참고자료1, 참고자료2 를 보니, 클라우드가 아닌 온프레미스 서 에서도 VPN을 통해서 EFS 파일 시스템에 연결할 수가 있다고 한다. 실제로 해보는건 성공시킨 다음에, 다음 포스팅에서 나눠서 써야겠다..

Comment  Read more

Database vs File system storage

|

개인 프로젝트를 진행하면서 데이터를 이리저리 수집해가던 와중에, 조언을 구하는 지인으로부터 데이터들을 데이터베이스에 저장하여 관리하는 것이 어떻냐는 조언을 듣게 되었다. 부끄럽게도 이전까지 데이터베이스를 통해 데이터들을 저장하는 방법을 사용해온 적이 없던터라 관련 자료를 알아보던 도중, 문득 왜 file system 이 아니라 DB이어야 할까라는 고민이 들었다. 이에 따라, Database vs File system storage 라는 주제에 대해 알아보고 정리한다.

참고자료 : stackoverflow, blog

데이터 베이스의 장점

  • ACID 일관성
    • ACID 는 데이터 베이스 내에서 파일의 I/O (transaction : 트랜잭션) 과정이 안전하게 수행되는 것을 보장하기 위해 필요한 성질을 의미한다.
      • Atomicity(원자성) : 트랜잭션과 관련된 일들이 실행되다가 중단되면 안된다. 즉, 하나의 트랜잭션은 성공, 실패를 함께 해야한다.
      • Consistency(일관성) : 데이터베이스 내의 데이터에 대한 무결성 조건을 위한하는 트랜잭션은 중단되는 것을 의미한다. 즉, 조건에 반하는 트랜잭션은 실행될 수 없다.
      • Isolation(고립성) : 트랜잭션 과정의 데이터를 확인하거나 다른 트랜잭션이 끼어들 수 없다. 고립성은 성능관련 이슈로 유연하게 적용된다고 한다.
      • Durabuility(지속성) : 적용된 트랜잭션은 영원히 반영되어야 한다. 예로 들어 커밋된 git이 version control로 인해 다시 이전으로 돌아가도 이전의 commit log는 지속적으로 남게 되는 것과 유사하다.
  • 상대적으로 안전하게 데이터를 저장할 수 있다.
  • ACID의 D로 인해서, 파일이 DB에 동기화되고 이에 대한 로그를 추적할 수 있어 관리가 용이하다.
  • 백업이 지원된다.
  • 서버-클라이언트 관계에서 서버 쪽에서 데이터를 공급해주는 것이 용이하다.

데이터 베이스의 단점

  • 음성 파일, 이미지 파일 등을 blob의 형태로 저장해야 한다.
    • blob 이란 말 그대로, 바이너리 처리된 데이터이다. 파이썬의 pickle data format 과 유사한 느낌이다.
  • 데이터베이스의 백업 작업은 무겁다. -> file system 또한 가볍지 않을 것 같다.
  • 메모리 비효율적이다.
    • RDBMS는 메모리를 사용해서 모든 데이터는 RAM에 얹어진다. 따라서 정렬, 인덱싱과 같은 쿼리문이 RAM에 실려서 많은 데이터를 다룰 경우 많은 리소스를 요구한다.
  • ACID 를 통해 relational mapping을 사용해야 하는데, 모든 데이터에 대해 이러한 관계 설정이 어렵다.

데이터 베이스는 이럴 때 적절하다.

  • 데이터가 구조화(structured)되어 있을 때
  • 데이터 간 관련성(relateness) 가 존재할 때
  • 데이터의 보안이 요구될 때
  • 작업에 필요한 데이터 갯수가 많지 않을 때

파일 시스템의 장점

  • 데이터의 위치가 잘 구조화되어 있다면 성능이 DB보다 좋을 수 있다. ex) Select * 쿼리를 통한 데이터 서치는 매우 느리다.
  • 수집한 데이터를 읽고 쓰는 것이 훨씬 간단하다.
  • 데이터를 마이그레이션(migration) 하는 것이 더 쉽다.
    • cloud storage 에 마이그래이션하는 것 또한 쉬워진다.
  • ACID 와 같은 무결정 보장 operation이 없기 때문에, 데이터를 트랜잭션하는 데에 별 신경을 쓰지 않아도 된다.

파일 시스템의 단점

  • DB이 경우 ACID operation을 통해 데이터의 무결성을 보장해주지만, file system의 경우 특정 데이터가 없거나 해킹되었을 때 이를 보장해주는 장치가 없다.
  • 상대적으로 덜 안전하다.

파일 시스템은 이럴 때 적절하다.

  • 큰 데이터가 요구될 때
  • 파일의 트랜잭션에 많은 사용자가 존재할 때

정리

아직도 크기가 큰 데이터에 대해 DB보다 file system이 더 적절한지 이해가 충분히 가지 않는다. 이 과정에서 DB의 transaction overhead, data duplication 등 많은 용어들이 나오는데, 이는 DB 자체에 대한 공부가 선행되어야 할 것 같다.

Comment  Read more

Universal Language Model Fine-tuning for Text Classification

|

gpt1ELMO 사이에 나온 논문, ULM-Fit 으로 잘 알려져 있는 논문에 대해 간략하게 리뷰해보도록 하겠습니다.

해당 논문을 읽다가, 처음부터 막히는 부분이 있었는데요. 바로 Introduction의 transductive transfer 와 inductive transfer 에 대한 내용이었습니다. 해당 링크 를 참고하여 나름대로 이해를 해본 결과를 정리해보겠습니다.

  • transductive transfer :
    • 말 그대로 unlabeled data를 통해 학습의 정확도를 향상시키는 것.
    • 전형적인 sem-supervised Learning
    • 논문의 예시로 pretrained embedding 이 있다.
  • Inductive transfer :
    • labeled data를 보고, unlabeled data를 예측하는 것
    • 전형적인 supervised learning

문제는 이 다음입니다. 이렇게 보면 ULM-Fit은 transductive transfer 이어야 하는데, 왜 inductive transfer라고 나와있을까요? (물론 저만 이해를 못하는 것일 수도 있습니다.) 이럴 때는 역시 짜맞추기를 해야겠죠? ULM-Fit에서 Universal 은 context representation 을 강화하기 위해서 universal scale로 단어를 임베딩한 단계를 의미합니다. 이 단계에서는 LM(Language Modeling) 을 통해서, 단어가 벡터로 표상됩니다.

그 다음에 fine-tuning이라는 bottleneck 과 유사한 projection layer가 들어가는데, 지도 학습을 통해 얇은 레이어의 파라미터가 학습되고 Fit 을 풀어쓴 것과 같이 for text classification 의 모델이 됩니다.

좀 더 자세히 보니 (짜맞추어 보니) pre-trained embedding과 다른 면이 보입니다. doc2vec, fasttext, glove과 같은 임베딩 벡터들은 unsupervised learning을 통해서 질높은 vector representation 을 구현하기 위한 기능을 하였습니다. ULM-Fit의 경우에는 언어 모델로 vector representation 을 강화시켰지만, 여기서 그치지 않고, fine-tuning이라는 프로세스를 거쳐 지도 학습의 형태로 information trasfer를 구현하였습니다.

해당 논문은 technical detail들이 다소 있다고 느껴졌던 논문이었습니다. 하나씩 살펴보면서 진행토록 하겠습니다.

General-domain LM pretraining

언어 모델을 학습시킬 때에는 단어의 도메인에 구애받지 않고, 넓은 분야의 단어들을 학습시켰습니다. (28,595 preprocessed Wikipedia articles and 103 millions words.) 가장 오래 걸리는 작업이지만, performance를 향상시키고, convergence를 빠르게 해준다고 합니다.

Target task LM fine-tuning

LM은 overfitting이 쉽게 된다는 단점이 있습니다. 이 문제를 해결하기 위해서 저자는 다양한 기술들을 가미했습니다.

Discriminative fine-tuning

아래의 공식은 gradient descent formula 입니다.

논문의 저자는 레이어 별로 다른 learning rate $\lambda$를 주는 방식을 사용하였습니다. 레이어가 1층부터 10층까지 있다고 했을 때, 더 높은 층으로 갈수록 더 적은 학습률을 할당하였습니다.

Slanted triangular learning rates

딥러닝 모델을 학습시킬 때, learning rate을 똑같이 주거나, 점점 decay 하는 방식을 많이 사용합니다. 하지만, 해당 논문에서 저자는 기울어진 삼각형의 모양을 띈 learning rate을 LM 모델에 적용하였습니다. 공식은 아래와 같습니다.

공식이 이것저것 나왔지만, 원리는 간단합니다. 우선 $T$는 training iteration의 횟수입니다. epoch 를 의미하는 것이 됩니다. $cut frac$은 전체 $T$에서 얼만큼의 iteration fraction이 진행되었을 때, learning rate가 치솟을지에 대한 정보이고, $cut$은 언제 learning rate이 감소하게 될지 그 iteration을 의미합니다. $p$는 얼마나 learning rate이 증가 및 감소할 지에 대한 ratio이고, 마지막으로 $ratio$는 max learning ratio 대비 min learning ratio 를 의미합니다.

Target task classifier fine-tuning

text classication의 경우 많은 단어들이 들어있는 document를 읽어드리게 됩니다. 이 경우 LM의 마지막 출력값이자 fine-tuning layer의 입력값을 last hidden state로 할 경우 많은 정보 손실이 발생하게 됩니다. 이와 같은 문제를 해결하기 위해서, 저자는 마지막 hidden state와 전체 hidden state의 max 값, mean 값을 사용하였습니다.

BPTT for Text Classication (BPT3C)

document classification에서는 긴 문서를 분류하게 되는데, 이 경우 BPTT의 특성에 따라서, gradient vanish 또는 explode 현상이 발생하게 될 수 있습니다. 이에 따라 저자는 BPTT3C라는 방법론을 제시하여, $L$ 길이의 문서를 $b$ 라는 fixed length로 나누고, 배치를 돌릴 때, gradient update를 tracking 하여 학습시키도록 하였습니다. (model is initialized with the final state of the previous batch;)

Bidirectional language model

마지막으로 ELMO와 같이, uni-directional 이 아닌, bi-directional 모델을 사용하였습니다.

Comment  Read more