
Hugging Face
개요
pytorch-pretrained-bert로 시작했던 허깅페이스가 이렇게나 커버렸다. Hub라는 플랫폼을 제공하며 Models, Datasets, Spaces(데모 용도)를 git-based로 호스팅한다.
Subword Tokenization
드물게 등장하는 단어를 더 작은 단위로 나눔
- BPE: GPT 사용. 단어를 유니코드 문자가 아닌 바이트 단위 구성으로 간주
- WordPiece: BERT 사용
- SentencePiece: BPE + Unigram LM Tokenizer
text = "Jack Sparrow loves New York!"
WordPiece는 York과 ! 사이에 공백이 없다는 정보를 잃어버리지만 SentencePiece는 U+2581 또는 아래 1/4 블록 문자로 할당해 공백 정보를 보존한다.1
Pipeline
trlX로 학습한 모델을 Transformers pipeline을 이용해 서비스하는 코드:
import json
from transformers import pipeline
from flask import Flask, request, jsonify
app = Flask(__name__)
rm = pipeline(task='sentiment-analysis', model="lvwerra/distilbert-imdb", device=0)
model_name = ['gpt', 'sft', 'ppo']
model = {
model_name[0]: pipeline(model="XXXX", device=1),
model_name[1]: pipeline(model="XXXX", device=2),
model_name[2]: pipeline(model="XXXX", device=3)
}
@app.route('/', methods=['GET', 'PUT'])
def index():
data = json.loads(request.data)
output = {}
score = {}
results = [
{
'model': 'megatron-gpt2-345m'
}
]
for m in model_name:
output[m] = model[m](data['prompt'], do_sample=True, top_p=0.95)
score[m] = rm(output[m][0]['generated_text'])
results.append({
m.upper(): output[m][0]['generated_text'],
'score': score[m][0]['score'] if score[m][0]['label'] == 'POSITIVE' else 1 - score[m][0]['score']
})
return jsonify(results)
app.run(host='0.0.0.0', port=XXXX)
실험:
$ curl -X PUT http://XXX.XXX.XXX.XXX:XXXX/ \
-H 'Content-Type: application/json' \
-d '{"prompt": "this movie was sucks!"}' | jq
Accelerate
$ accelerate config
로 설정. 설정 파일 기본 저장 위치 ~/.cache/huggingface/accelerate/default_config.yaml
compute_environment: LOCAL_MACHINE
distributed_type: FSDP
downcast_bf16: 'no'
fsdp_config:
fsdp_auto_wrap_policy: TRANSFORMER_BASED_WRAP
fsdp_backward_prefetch_policy: BACKWARD_PRE
fsdp_offload_params: false
fsdp_sharding_strategy: 1
fsdp_state_dict_type: FULL_STATE_DICT
fsdp_transformer_layer_cls_to_wrap: LlamaDecoderLayer
machine_rank: 0
main_process_ip: bcm-dgxa100-0001
main_process_port: 30001
main_training_function: main
mixed_precision: bf16
num_machines: 8
num_processes: 8
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false
Launching a script from the location of that custom yaml file looks like the following:
$ accelerate launch --config_file ${PWD}/scripts/accelerate_config.yaml {script_name.py} {--arg1} ...
Accelerate CLI
accelerate를 slurm 환경에서 구동해야 하는 이슈가 있어 다음과 같이 스크립트를 구성하고 default_config.yaml은 사용하지 않는 형태로 정리했다. export
가 실행하는 부분은 미리 sbatch
로 실행. accelerate가 분산 실행하므로 tasks per node는 1로 설정.
#SBATCH --ntasks-per-node=1
export HOSTNAMES=$(scontrol show hostnames "$SLURM_JOB_NODELIST")
export COUNT_NODE=$(scontrol show hostnames "$SLURM_JOB_NODELIST" | wc -l)
...
H=$(hostname)
MACHINE_RANK=$(echo -e $HOSTNAMES | python3 -c "import sys;[sys.stdout.write(str(i)) for i,line in enumerate(next(sys.stdin).split(' ')) if line.strip() == '$H'.strip()]")
echo machine_rank="${MACHINE_RANK}"
PYTHONPATH=/FastChat accelerate launch \
--num_processes $(( 8 * ${COUNT_NODE} )) \
--num_machines ${COUNT_NODE} \
--dynamo_backend 'no' \
--mixed_precision bf16 \
--machine_rank ${MACHINE_RANK} \
--main_process_ip ${MASTER_ADDR} \
--main_process_port ${MASTER_PORT} \
--use_fsdp \
--fsdp_offload_params false \
--fsdp_sharding_strategy 1 \
--fsdp_auto_wrap_policy TRANSFORMER_BASED_WRAP \
--fsdp_transformer_layer_cls_to_wrap LlamaDecoderLayer \
--fsdp_backward_prefetch_policy BACKWARD_PRE \
--fsdp_state_dict_type FULL_STATE_DICT \
fastchat/train/train.py \
...
load_model
GPU 메모리에 모델을 올리려면 CPU 메모리도 그 이상이 확보되어야 한다. 그렇지 않으면 올리다가 killed. AWS에서 g5.xlarge는 A10G 24G지만 CPU 메모리가 16G라서 모델이 올라가지 않는다. 허깅 페이스에서는 CPU, GPU 메모리를 구분하지만 CPU 메모리 지정이 정확해도 killed. 필요 조건: GPU 메모리 < CPU 메모리 g5.2xlarge 이상.
모델에서 파라미터를 8bit quantization 했을 때 속도 문제가 있음. 1/2 속도로 느려졌다.
-
p142, 트랜스포머를 활용한 자연어 처리 ↩
Last Modified: 2023/07/10 21:22:19