五種搭建LLM服務的方法和代碼示例
在不斷發展的大型語言模型(LLMs)領域中,用于支持這些模型的工具和技術正以與模型本身一樣快的速度進步。在這篇文章中,我們將總結5種搭建開源大語言模型服務的方法,每種都附帶詳細的操作步驟,以及各自的優缺點。
1、Anaconda + CPU
我們首先介紹門檻最低的入門級方法,因為這個方法不需要GPU,基本上只要有一個還不錯的CPU和足夠RAM就可以運行。
這里我們使用llama.cpp及其python綁定llama-cpp-python
pip install llama-cpp-python[server] \
--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu
創建一個名為models/7B的目錄來存儲下載的模型。然后使用命令下載GGUF格式的量化模型:
mkdir -p models/7B
wget -O models/7B/llama-2-7b-chat.Q5_K_M.gguf https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGUF/resolve/main/llama-2-7b-chat.Q5_K_M.gguf?download=true
然后就可以運行以下命令啟動服務器:
python3 -m llama_cpp.server --model models/7B/llama-2-7b-chat.Q5_K_M.gguf
將環境變量MODEL設置為下載模型的路徑。然后運行openai_client.py腳本就可以訪問我們的查詢服務器。openai_client.py使用OpenAI庫調用LLM服務器并打印響應。
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": "What are the names of the four main characters of South Park?",
},
]
因為這個方法是門檻最低的,所以他的速度也是最慢的,基于Intel?Core?i9-10900F CPU @ 2.80GHz的系統的處理時間大概是13秒左右,所以這個方法一般用作我們的本地測試服務(如果你GPU不夠的話)。
2、Anaconda + GPU
前面的CPU方法是非常慢的,為了加快速度我們將使用vllm,這是一個專門為有效利用gpu而設計的工具。
pip install vllm
執行以下命令來啟動服務器:
python -m vllm.entrypoints.openai.api_server --model TheBloke/Llama-2-7B-Chat-AWQ --api-key DEFAULT --quantization awq --enforce-eager
這將下載AWK量化模型并啟動一個OpenAI兼容服務器,我們可以像使用llama.cpp一樣進行查詢。
“— enforce-eager”是費差個重要的,因為它允許模型在我的10G VRAM GPU中運行,沒有內存不足的錯誤。
在Nvidia RTX 3080 GPU和Intel?Core?i9-10900F CPU的系統下處理時間只有0.79s。CPU快20倍左右,這就是為什么GPU現在都那么貴的一個原因。
這種方式可以用做我們測試服務器或者在線上的小規模部署,如果要求不高,也可以當作生產環境來使用,當然維護起來非常麻煩。
3、Docker + GPU
vllm有很多依賴,如果要批量的安裝是一件非常耗時的事情。好在vllm還提供了一個預構建的docker映像,它已經包含了所需的所有庫。
對于ubuntu,我們首先安裝Nvidia CUDA Toolkit,如果安裝了則跳過
sudo apt install nvidia-cuda-toolkit
然后添加Nvidia Docker存儲庫并安裝Nvidia Container Toolkit:
distributinotallow=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
配置Docker使用Nvidia runtime:
sudo tee /etc/docker/daemon.json <<EOF
{
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
EOF
sudo pkill -SIGHUP dockerd
然后就可以運行我們的模型了
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 \
--ipc=host \
vllm/vllm-openai:latest \
--model TheBloke/Llama-2-7B-Chat-AWQ \
--quantization awq --enforce-eager
這里我們使用-v參數將本地的磁盤映射到容器中,這樣所有的容器都可以使用huggingface的模型緩存,避免了重復下載。
docker的部署方式處理一個查詢的時間在0.8s左右與使用相同硬件在Anaconda上運行vllm相似。
使用docker可以大大簡化我們服務器的環境配置,配合集群管理腳本可以適用于大規模的服務部署。
上面的方式都適用于本地和有GPU主機/集群的方式,下面我們介紹2個比較簡單的云GPU的方案,這兩個方案都是按需付費的。
4、modal
Modal可以簡化無服務器應用程序的部署,特別是那些利用GPU資源的應用程序。它的一個突出的特點是它的計費模式,它確保用戶只在他們的應用程序使用GPU資源的持續時間內收費。這意味著當你的應用程序不被使用時則不會收費。
Modal還提供每月30美元的優惠,為用戶提供了充分的機會來探索和試驗部署gpu加速的應用程序,而無需支付前期費用,這也是我們介紹他的一個原因,因為每月目前還能白嫖30美元,哈。
首先安裝:
pip install modal
然后配置modal的運行環境,這一步需要登陸了
modal setup
我們這里的vllm_modal_deploy.py改編Modal的官方教程。這個腳本最重要的一點是定義GPU。這里我選擇了nvidia T4,因為量化模型非常小:
# https://modal.com/docs/examples/vllm_mixtral
import os
import time
from modal import Image, Stub, enter, exit, gpu, method
APP_NAME = "example-vllm-llama-chat"
MODEL_DIR = "/model"
BASE_MODEL = "TheBloke/Llama-2-7B-Chat-AWQ"
GPU_CONFIG = gpu.T4(count=1)
然后定義運行代碼的docker鏡像:
vllm_image = ( # https://modal.com/docs/examples/vllm_mixtral
Image.from_registry("nvidia/cuda:12.1.1-devel-ubuntu22.04", add_pythnotallow="3.10")
.pip_install(
"vllm==0.3.2",
"huggingface_hub==0.19.4",
"hf-transfer==0.1.4",
"torch==2.1.2",
)
.env({"HF_HUB_ENABLE_HF_TRANSFER": "1"})
.run_function(download_model_to_folder, timeout=60 * 20)
)
定義App:
stub = Stub(APP_NAME)
最后編寫預測的類:
class Model:
@enter() # Lifecycle functions
def start_engine(self):
import time
from vllm.engine.arg_utils import AsyncEngineArgs
from vllm.engine.async_llm_engine import AsyncLLMEngine
print("?? cold starting inference")
start = time.monotonic_ns()
engine_args = AsyncEngineArgs(
model=MODEL_DIR,
tensor_parallel_size=GPU_CONFIG.count,
gpu_memory_utilizatinotallow=0.90,
enforce_eager=False, # capture the graph for faster inference, but slower cold starts
disable_log_stats=True, # disable logging so we can stream tokens
@enter()裝飾器被用來定義生命周期方法來處理代碼的初始化之類的事情。所以我們在這里加載模型并設置生成管道。如果查詢觸發了此方法,則意味著有一個“冷啟動”,也就是第一次啟動的耗時會比較長。
定義生成函數:
@stub.function()
def generate(user_question: str):
model = Model()
print("Sending new request:", user_question, "\n\n")
result = ""
for text in model.completion_stream.remote_gen(user_question):
print(text, end="", flush=True)
result += text
return result
最后就是使用命令行進行部署
modal deploy vllm_modal_deploy.py
部署完成后就可以從python調用這個函數:
import timeit
import modal
APP_NAME = "example-vllm-llama-chat"
f = modal.Function.lookup(APP_NAME, "generate")
start_time = timeit.default_timer()
print(f.remote("What are the names of the four main characters of South park?"))
elapsed = timeit.default_timer() - start_time
print(f"{elapsed=}")
經過我的測試第一次啟動大約需要37秒。這包括啟動時間和處理時間。應用程序已經啟動時的延遲是2.8秒。這些都是在Nvidia T4上運行的,所以3秒還是可以接受的。
需要注意:container_idle_timeout的值是用來回收容器的,超過了這個時間值會進行回收,這樣再次啟動就會調用初始化的過程,也就是我們說的冷啟動。但是因為modal的計費方式,再未回收前都是計費的,所以請謹慎修改。
最后說下費用:Modal的Nvidia T4收費是0.000164 * /秒 或 0.59 * /小時。上面我們使用了幾百秒的計算時間,花費了大約0.1美元。
5、AnyScale
Anyscale與Modal類似,但他更專注于提供隨時可用的開源模型。我們可以使用Anyscale API的URL直接調用它們。
首先注冊并獲得API密鑰。你可以使用他們提供給新用戶的10*$免費套餐來運行本教程。
接下來,我們將使用與之前相同的openai_client.py腳本:
export API_KEY="CHANGEME"
export MODEL="meta-llama/Llama-2-7b-chat-hf"
export BASE_URL="https://api.endpoints.anyscale.com/v1"
python openai_client.py
不需要任何的設置,只要我們在發送請求時修改參數就可以訪問不同的模型了,這就是Anyscale的優勢
這個請求的延遲大約是3.7秒,還算不錯。但是AnyScale是按照令牌來計費的(與OpenAI的API相同)LLama2 7B 的價格是0.15*$ / 1M 令牌。我們運行這個示例花費不到1/10美分。
可以看到AnyScale還是很不錯的,對于開源模型我們直接可以拿來使用,并且花費也很低,如果你沒有GPU,這個可以作為模型測試的首選平臺,一個月幾十美元基本上夠我們測試當月新發布的所有模型了。
總結
當涉及到服務大型語言模型(llm)時,有各種各樣的方法可以選擇:
對喜歡本地服務器設置的人來說,使用帶有CPU的Anaconda提供了較低的進入門檻,gpu加速的Anaconda環境可以緩解延遲問題,但它仍然面臨可伸縮性和對本地資源的依賴方面的限制,特別是在處理大型llm時。
Docker可以簡化Python環境配置,可以適應大批量的部署。
Modal提供了一種更靈活的按次付費計算解決方案,使其具有成本效益和易于設置的吸引力。
AnyScale提供了較低的進入門檻對于那些追求簡單的人來說是一個非常好的選擇。
我們介紹的這些方法是一個很好的起點,還有很多其他服務比如runpod和AWS,但這些方法需要更多的運維知識,并且在小規模部署上優勢并不明顯,所以要考慮對針對特定需求和要求量身定制的最佳方案還需要進行全面評估。