안녕하세요?
질문 별로 답변 드리겠습니다.
- Fine-tuning weight 적용 가능성: 저희가 Fine-tuning한 weight를 Furiosa artifact에 적용하는 것이 가능한지 궁금합니다. 만약 가능하다면, 추론 정확도를 유지하면서 throughput 개선도 함께 기대할 수 있을까요?
fine-tuning weight 를 적용하는 의도된 워크플로우는 모델을 컴파일하는 것 입니다. 이미 컴파일된 아티팩트에 weight만 직접 교체하는 것은 다음 이유로 현실적인 어려움이 있습니다. model artifact 에는 모델 코드 등에 포함된 상수 등은 컴파일 단계에서 constant folding 등이 적용되어 NPU program 자체에 포함되어 있는데요. 이런 부분에 차이가 전혀 없는지 사람이 확인하는 것은 쉽지 않기 때문에 weight만 교체만 하는 것은 권장하고 있지 않습니다.
또한 fine-tune 된 모델들의 경우 model config (transformers 저장 포맷의 config.json)에 아키텍쳐에 영향을 주는 미세한 어떤 변경도 없어야 실행에 문제가 없는데요. 이런 부분을 사용자들이 직접 확인하게 하는 방법은 워크플로우 상 좋은 방법은 아니기 때문에 직접 weight 교체 하는 방법은 아직 고려하고 있지는 않습니다.
서두에 말씀 드린 것 처럼 위 문제를 사용자가 직접 핸들링 하지 않는 방법은 컴파일인데요. 컴파일하여 furiosa artifact 로 만드는 과정은 최적화 정도 (주로 버켓의 개수) 따라 (모델 파라메터나 캐쉬가 아예 없는 상황에서는) 시간이 수 분에서 몇 시간도 걸릴 수 있습니다. 그러나 이 시간은 1회성 비용으로 컴파일 후에는 컴파일의 중간 결과들이 캐쉬되어 모델 아키텍쳐가 변하지 않는 한 다시 컴파일 할 경우 빠른 시간에 컴파일이 완료되게 됩니다.
- 동일 성능 재현 방법: 저희 모델을 기반으로
furiosa_llm
빌드를 수행했을 때, Artifact와 동일한 수준의 성능을 재현할 수 있을까요? 이를 위해 필요한 빌드 옵션이나 설정이 구체적으로 무엇인지 알고 싶습니다.
네 물론입니다. 커맨드 또는 Python 코드로 컴파일 하실 수 있는데요. 버켓 설정이 많다보니 Python 코드로 공유 드립니다. 아래 코드가 아티팩트 생성에 사용된 코드입니다. 아티팩트 생성에 사용하는 설정 등은 Huggingface hub의 모델에 같이 올려두는 식으로 공개를 고려하도록 하겠습니다.
또한, 아래 예제에서 meta-llama/Llama-3.1-8B-Instruct
대신에 Huggingface Hub의 다른 모델 repo 를 지정하시거나 local path 를 지정하시면 됩니다.
추가로 아래 모델 artifact는 상당히 범용적으로 만들어진 것이라 버켓 설정이 많고 그로 인해 환경에 따라 컴파일 시간이 몇 시간 정도 걸릴 것으로 예상됩니다. 다만 이 시간은 cache가 아예 없는 시스템에서 발생하는 일회성 시간이고 컴파일을 한번이라도 진행 하신 뒤에는 반복하면 빠르게 진행되니 이 부분 유념 부탁드립니다. 또한 필요에 따라 버켓이 조금 줄이셔도 됩니다. 버켓에 대한 가이드가 아직 잘 작성되어 있지 않은데요. 이 부분은 제가 조만간 작성해서 Furiosa Docs 에 올리고 업데이트 드리겠습니다.
from furiosa_llm.artifact.builder import ArtifactBuilder
RELEASE_PREFILL_BUCKETS = [
(1, 256), (1, 320), (1, 384), (1, 512), (1, 640), (1, 768), (1, 1024), (2, 1024), (4, 1024),
]
RELEASE_DECODE_BUCKETS = [
*[(1, 1024), (4, 1024), (8, 1024), (16, 1024), (32, 1024), (64, 1024)],
*[(1, 2048), (4, 2048), (8, 2048), (16, 2048), (32, 2048)],
*[(1, 4096), (4, 4096), (8, 4096), (16, 4096), (32, 4096)],
*[(1, 8192), (4, 8192), (8, 8192), (16, 8192)],
*[(1, 16384), (4, 16384), (8, 16384)],
*[(1, 32768), (4, 32768)],
]
builder = ArtifactBuilder(
"meta-llama/Llama-3.1-8B-Instruct",
"<any name>",
tensor_parallel_size=8,
prefill_buckets=RELEASE_PREFILL_BUCKETS,
decode_buckets=RELEASE_DECODE_BUCKETS,
max_seq_len_to_capture=32 * 1024,
prefill_chunk_size=8 * 1024,
)
builder.build("./Output-Llama-3.1-8B-Instruct",
num_pipeline_builder_workers=8,
num_compile_workers=1)
- 추가 최적화 기법 필요 여부: Artifact와 유사한 성능 최적화를 이루기 위해, 빌드 옵션 외에도 추가적으로 고려하거나 적용해야 할 다른 최적화 기법(예: Paged attention, Rotation embedding 등)이 있는지도 궁금합니다.
런타임 레벨에서는 어떤 병렬화 전략을 사용하는지나 npu_queue_limit 과 같이 동시에 몇 개 요청을 npu에 요청하게 할지 등을 선택하실 수 있습니다. 다만 모델 레벨에서는 Furiosa-LLM과 Furiosa Compiler가 최적의 방법을 찾아 자동으로 적용하는 방법을 사용하고 있고 말씀 하신 최적화는 기본적으로 자동으로 적용하고 있어 원본 모델 그대로 사용하시면 이미 실험하셨던 model artifact와 동일한 성능을 그대로 재현하실 수 있습니다.
궁금하신 점은 편히 질문 주세요.