透過 PCIe 執行 GenAI 模型
| 欄位 | 值 |
|---|---|
| 類別 | PCIe 協同處理 |
| 難度 | 中級 |
| 預估閱讀時間 | 15 minutes |
| 標籤 | PCIe, GenAI, LLM, VLM, Whisper |
每個範例都會載入主機上已準備好的 LLiMa 模型目錄,執行具有上限的請求,然後關閉模型。請先分別執行各範例。它們使用相同的連線設定,但請求輸入不同。
操作指南
載入 LLM
在 C++ 中建立 pcie::genai::GenAIModel,或在 Python 中建立 pyneatpcie.genai.GenAIModel。建立時會將模型載入卡上,不需要 build() 或選擇佇列。設定 connection.card_id 以選擇卡。可使用模型的絕對路徑,或相對於目前工作目錄的路徑。
pcie_host/tutorials/029_run_genai_over_pcie/run_llm.cpp
genai::GenAIModel model(args.model, args.connection);
if (!model.accepts_text() || model.task() == genai::GenAITask::ASR)
throw std::invalid_argument("choose a text-generation model directory");
傳送文字請求
設定 prompt 與 max_new_tokens,然後呼叫 run()。結果包含回答文字與生成指標。範例預設最多生成 128 個權杖;可使用 --max-tokens 更改上限。
pcie_host/tutorials/029_run_genai_over_pcie/run_llm.cpp
genai::GenerationRequest request;
request.prompt = args.prompt;
request.max_new_tokens = args.max_tokens;
if (!args.stream) {
const auto result = model.run(request);
std::cout << result.text << '\n';
std::cout << "Generated tokens: " << result.metrics.generated_tokens << '\n';
}
串流回答
向 LLM 範例傳入 --stream,即可改為逐一處理 TokenSample。每個文字片段到達時立即印出;最終樣本包含完整的生成指標。每個模型同一時間只能有一個進行中的請求。
pcie_host/tutorials/029_run_genai_over_pcie/run_llm.cpp
auto stream = model.stream(request);
for (const auto& sample : stream) {
std::cout << sample.text << std::flush;
if (sample.is_final)
std::cout << "\nGenerated tokens: " << sample.metrics.generated_tokens << '\n';
}
關閉模型
C++ 在推論後明確呼叫 close(),若例外中斷範例,則由解構函式進行清理。Python 使用內容管理器,在離開區塊時關閉模型,發生錯誤時亦然。連線逾時均有上限:啟動 15 分鐘,請求 5 分鐘。
pcie_host/tutorials/029_run_genai_over_pcie/run_llm.cpp
model.close();
準備 RGB 圖片
VLM 範例在主機上使用 OpenCV 讀取圖片,將 BGR 轉換為 RGB,並產生形狀為 [H, W, 3] 的連續 UInt8 像素。C++ 將擁有像素資料的向量包裝為 PCIe 張量;Python 則提供 NumPy 陣列。請勿正規化像素,也不要改用卡上的本機圖片路徑。
pcie_host/tutorials/029_run_genai_over_pcie/run_vlm.cpp
const auto bgr = cv::imread(args.media, cv::IMREAD_COLOR);
if (bgr.empty())
throw std::invalid_argument("cannot read image: " + args.media);
cv::Mat rgb;
cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
if (!rgb.isContinuous())
rgb = rgb.clone();
auto image = pcie::Tensor::from_vector(
std::vector<std::uint8_t>(rgb.data, rgb.data + rgb.total() * rgb.elemSize()),
{rgb.rows, rgb.cols, 3}, "", pcie::PixelFormat::RGB);
詢問圖片內容
載入 VLM,將 RGB 輸入與提示一起放入 request.images。模型會自行處理圖片前處理。傳回的文字就是問題的回答;PCIe 請求沒有圖片檔案欄位。
pcie_host/tutorials/029_run_genai_over_pcie/run_vlm.cpp
genai::GenAIModel model(args.model, args.connection);
if (!model.accepts_image())
throw std::invalid_argument("choose a vision-language model directory");
genai::GenerationRequest request;
request.prompt = args.prompt;
request.images = {image};
request.max_new_tokens = args.max_tokens;
std::cout << model.run(request).text << '\n';
model.close();