fgenie / rims_minimal

Been lazy enough to pull over again to the end!
0 stars 1 forks source link

VLLM 서빙 및 포워딩 #45

Closed fgenie closed 1 month ago

fgenie commented 1 month ago

접속 관련한 정보는 DM으로 전달드리겠습니다.


현재 다음의 docker 명령어로 Phi3-mini-128k 를 서빙할 수 있음을 확인했고 긴 길이에 대해서도 문제없이 작동함까지는 확인했습니다.

# @dgx-a100:  
# ~taeng/vllm_from_dockerhub.sh 

ext_ip=7870 # 8513 # 왼쪽 둘은 중간 호스트에 노출되어있는 포트
docker run --runtime nvidia --gpus '"device=0"' --rm \
    -v /home/taeng/data:/root/.cache/huggingface \
    -p $ext_ip:8000 \
    --ipc=host \
    vllm/vllm-openai:latest \
    --model microsoft/Phi-3-mini-128k-instruct --trust-remote-code 




1. intermediate host 를 통해서 port tunneling이 가능한지 테스트 부탁드립니다.

현재는 ssh 터널링을 통해서 학교 서버팜에 존재하는 dgx에 접근하고 있습니다. 이 때문에 dgx 에서 서빙중인 모델을 다른 호스트에서 쿼리해가며 디버깅하는 것에 불편함이 있는데요. 어제 제가 태형님과 intermediate host에서 접근 가능한 ip, 및 포트를 확인했습니다. 중간 호스트는 학교 외부에서도 접근이 가능한 것이라 이 호스트에서 포트 터널링을 해주면 로컬에서 실시간으로 디버깅이 가능할 것 같아요.

chatgpt에 따르면 아래같은 명령어로 서비스중인 호스트와 포트를 터널링 할 수 있는 것처럼 얘기해주더라고요 (맞는지는 모름)

보안상의 문제가 있을 수 있으니 중간 호스트의 접근방식과 관련 포트 정보는 따로 전달드리겠습니다

ssh -L [local_port]:[target_host]:[target_port] -p [intermediary_port] [user]@[intermediary_host]




2. tokenizer --max-model-len [CUSTOMLENGTH e.g. 12000]을 사용했을 때 RoPE theta 에 영향이 있는지 확인해주세요.

위는 다음 파라미터를 함께 쓰기 위한 tweak 입니다. --gpu-memory-utilization 0.5

원래 모델에 달려있는 default configuration (tokenizer_config.json?) 에 따르면 모델이 수용할 수 있는 maxlen은 위보다 열 배 이상 큽니다. A100-80GiB 1장의 절반만 활용해야하는 경우도 자주 있는데, 그럴 경우에 기본값으로는 모델 서빙이 불가능해서 이를 줄여보았습니다. 그런데 이렇게 했을 때 position embedding hyperparameter에 의도치 않은 혹은 악영향을 끼칠 수 있는 것인지 확인이 필요합니다. 이를 확인해주세요.




3. chat template 을 확인하고 일치시켜주세요

혹시 ollama 템플릿이 이상한 건 아닌지 해당사항을 먼저 확인 부탁드릴게요 그리고 만약 ollama template 과 huggingface template 둘 중 어느것을 취해도 상관이 없다면 system이 있는 ollama버전으로 일치를 부탁드립니다

ollama template 에는 system 이 존재하고 huggingface 에는 존재하지 않는 것처럼 보입니다.

ollama에서 보여주는 챗 템플릿을 tokenizer_config.json에 포함할 수 있도록 jinja2로 작성해주세요.

아마 적용은 vllm 소스 중 아래 스크립트에서 하고 있는 것 같습니다. serving_chat.py from vllm source (아마 vllm/entrypoints/openai/serving_chat.py? )

strutive07 commented 1 month ago

1. intermediate host 를 통해서 port tunneling이 가능한지 테스트 부탁드립니다.

ssh -L [local_port]:[target_host]:[target_port] -p [intermediary_port] [user]@[intermediary_host] -Nf

위 명령어를 사용하면 로컬에서 dgx machine에 떠있는 vllm에 접근할 수 있습니다.

image

strutive07 commented 1 month ago

2. tokenizer --max-model-len [CUSTOMLENGTH e.g. 12000]을 사용했을 때 RoPE theta 에 영향이 있는지 확인해주세요.

https://github.com/vllm-project/vllm/pull/4298/files

https://github.com/vllm-project/vllm/blob/main/vllm/model_executor/models/__init__.py#L49

microsoft/Phi-3-mini-128k-instruct 는 vllm에서 LlamaForCausalLM 구현체로 동작함.

여기서 호출되는 get_rope 구현체는 여기

인데, 이는 config.json의 original_max_position_embeddings 에만 영향을 받음 (length관련 옵션들 중).

따라서, --max-model-len 는 rope에 영향을 주지 않음.

strutive07 commented 1 month ago

3. chat template 을 확인하고 일치시켜주세요

vllm openai api server는 tokenizer_config.json 의 chat_template을 기본 옵션으로 사용합니다.

따라서 현재 사용되고있는 chat template은 이렇게 됩니다.

"{{ bos_token }}{% for message in messages %}{% if (message['role'] == 'user') %}{{'<|user|>' + '\n' + message['content'] + '<|end|>' + '\n' + '<|assistant|>' + '\n'}}{% elif (message['role'] == 'assistant') %}{{message['content'] + '<|end|>' + '\n'}}{% endif %}{% endfor %}"

https://huggingface.co/microsoft/Phi-3-mini-4k-instruct/discussions/51#66328cab9292069aed6a425b 추가로, offical repo의 comment에서 system prompt를 지원하지 않는다고 언급하고있습니다.

3.1 system prompt를 user prompt로 넣거나, user promt 상단에 넣는 방법에 대해

https://huggingface.co/microsoft/Phi-3-mini-4k-instruct/discussions/51#663403bddeb469bd91dd7a98

phi3 측에서 system prompt 적용 방법에 대해 실험중이라는 코멘트가 1달 전에 올라왔었고, 아직 업데이트가 없습니다. 만약 user prompt 상단에 concat하는 형식이면 tokenizer_config.json을 그대로 사용하고 data 주입 당시에 system prompt를 넣어주면 될 것 같습니다.

다만 이상하게도 https://huggingface.co/microsoft/Phi-3-mini-4k-instruct/blob/main/added_tokens.json 에는 <|system|> token이 존재합니다.

따라서 아래 3가지 옵션에 대해 성능이 가장 잘 나오는 것을 실험으로 하나 뽑아야 할 것 같습니다.

system prompt를 첫 번째 user prompt 에 포함하여 사용

system prompt를 user token을 사용하여 표현

"{{ bos_token }}{% for message in messages %}{% if (message['role'] == 'user' or message['role'] == 'system') %}{{'<|user|>' + '\n' + message['content'] + '<|end|>' + '\n' + '<|assistant|>' + '\n'}}{% elif (message['role'] == 'assistant') %}{{message['content'] + '<|end|>' + '\n'}}{% endif %}{% endfor %}"

system prompt를 system token을 사용하여 표현

"{{ bos_token }}{% for message in messages %}{% if (message['role'] == 'user') %}{{'<|user|>' + '\n' + message['content'] + '<|end|>' + '\n' + '<|assistant|>' + '\n'}}{% elif (message['role'] == 'system') %}{{'<|system|>' + '\n' + message['content'] + '<|end|>' + '\n'}}{% elif (message['role'] == 'assistant') %}{{message['content'] + '<|end|>' + '\n'}}{% endif %}{% endfor %}"
fgenie commented 1 month ago

감사합니다 마지막 jinja는 조금 수정하여 사용했습니다