2019년 10월 8일 화요일

H2O DriverlessAI에서 큰 dataset을 학습할 때 memory를 적게 사용하도록 하는 설정 방법


H2O DriverlessAI는 서버 메모리를 많이 사용하는 솔루션입니다.  기본적인 rule of thumb은 training dataset의 10배 크기의 서버 메모리가 필요하다는 것입니다.  즉, 만약 training dataset이 30GB라면, 서버 메모리는 300GB 이상 있어야 합니다.

그런데 살다보면 training dataset이 30GB인데 서버 메모리는 100GB 밖에 안 되는 경우도 있습니다.  이런 경우에는 H2O DriverlessAI는 쓰지 못하는 것일까요?  꼭 그렇지는 않습니다.

H2O DriverlessAI는 기본적으로 'data가 너무 크다'라고 생각하면 down-sampling이라는 것을 합니다.  즉, data 중에서 일부만 발췌헤서 training에 사용하는 것입니다.

그렇다면 당연히 몇가지 의문이 생깁니다.

1.  '너무 크다'라는 것의 기준은 무엇인가?

당연히 기준이 있어야 하는데, 그건 H2O DriverlessAI의 config.toml이라는 파일 속에 있습니다.  이 파일은 H2O DriverlessAI의 설치 home directory에 들어있습니다.  기본적으로는 아래와 같이 statistical_threshold_data_size_large = 500000000 라는 parameter에 의해 정해지는데, 이 값은 default가 500M으로 되어 있고, 이 값은 data의 byte 수 등이 아니라 rows * columns 의 숫자입니다.   즉, 가령 50개의 column을 가진 CSV 파일의 row수가 10M을 넘어간다면 H2O DriverlessAI는 이 dataset이 '너무 크다' 라고 판단합니다.

[user612@p612-met1 dai-1.7.1-linux-ppc64le]$ vi ./config.toml
...
# Internal threshold for number of rows x number of columns to trigger certain statistical
# techniques (fewer genes created, removal of high max_depth for tree models, etc.) that can speed up modeling.
# Also controls maximum rows used in training final model,
# by sampling statistical_threshold_data_size_large / columns number of rows
#statistical_threshold_data_size_large = 500000000


2. 이 파라미터를 어떻게 얼마나 조정해야 하는가?

만약 이 기본값으로 training할 때 서버 메모리 부족으로 error가 난다면, 이 기준값을 내려야 합니다.  제가 해보니 이 수치가 정확하게 rows * columns를 맞추는 것은 아니니, 정확하게는 try & error를 통해 경험치로 조정하셔야 합니다.  아무튼 이것을 수정하는 방법은 저 config.toml 파일을 수정한 뒤 H2O DriverlessAI를 retstart 하는 것입니다.   아래의 예는 그 기준을 1/5f로 줄인 것입니다.

[user612@p612-met1 dai-1.7.1-linux-ppc64le]$ vi ./config.toml
...
#statistical_threshold_data_size_large = 500000000
statistical_threshold_data_size_large = 100000000


3. Sampling은 어떤 기준으로 이루어지는가? 

기본적으로 sampling 할 때는 알아서 적절히 하게 되어 있습니다.  특히 현재 training하려는 문제의 결과가 regression(결과가 숫자로 나오는 경우)의 경우와 classification(몇가지 정해진 카테고리 중 하나로 나오는 것)의 경우에 대해 각각 다릅니다.

- Regression의 경우 : Random sampling (마구잡이 샘플링)
- Classification의 경우 : Stratified sampling (계층별 샘플링)

그런데 특히 sparse data에 대한 classification인 경우, 즉 신용카드사의 정상/비정상 거래처럼 대부분은 정상이고 극히 일부만 비정상 거래인 경우에는 그렇쟎아도 부족한 비정상 거래 data 건수가 더 줄어들지 않을까 염려됩니다.  만약 그렇게 class별로 record 수가 5배 이상 차이가 날 경우, H2O DriverlessAI는 알아서 그 dataset을 imbalanced dataset이라고 판단하고 그에 따라 sampling을 진행합니다.

이런 imbalanced sampling는 "Expert Settings" tab의 "MODEL" 메뉴에서 조정이 가능하며, 다음과 같이 여러가지 방법을 제공합니다.




어떤 sampling 방법이 가장 좋은지에는 정답이 없습니다만, 위에서 언급한 신용카드 사기 거래 dataset과 같이 imbalance가 심한 dataset에서는  잘 판단이 서지 않을 때는 일단 Over_under_sampling을 택하는 것이 낫지 않을까 합니다.  (저는 일일이 테스트 해보지는 못했습니다.)

Automatic :  모든 class를 필요에 따라 적절히 sampling (default)
Over_sampling : 소수 class를 더 많이 sampling하여 균형을 맞춤
Under_sampling : 다수 class를 더 적게 sampling하여 균형을 맞춤 
Over_under_sampling : 소수 class는 over sampling하고 다수 class는 under sampling하여 균형을 맞춤
Off : Sampling을 하지 않음




4. 이렇게 down-sampling하면 결과로 만들어지는 accuracy에 저하가 발생하지 않는가 ?

당연히 일부 발생할 수도 있습니다.  그런 저하를 용납할 수 없는 상황이시라면 서버 메모리를 더 사셔야 합니다...



## Training의 메모리 필요량을 줄이는 다른 기본적인 방법들 

1.  Accuracy Dial을 낮춘다

- Accuracy를 높일 수록 좀더 많은 model을 적용해보기 때문에 당연히 메모리 사용량이 늘어납니다.  Accuracy dial을 3~4 정도로 낮게 두면 메모리 사용량이 극적으로 줄어듭니다.  그럴 경우 당연히 accuracy도 떨어진다는 단점이 있습니다.

2.  Expert Settings tab 중 'MODEL' 메뉴에서 lightGBM을 제외한 모든 model을 off 시킨다

- 무조건 많은 model을 적용한다고 accuracy가 다 높아지는 것은 아닙니다.  실제로 대부분의 경우 lightGBM과 XGBoost에서 가장 좋은 accuracy가 나옵니다.  따라서, Rulefit이나 GLM, Tensorflow 등의 모델들을 off 시켜 놓으면 역시 메모리 사용량이 극적으로 줄어듭니다.  물론 accuracy도 좀 떨어지긴 합니다.






댓글 없음:

댓글 쓰기