rt-541

writing / 2026-09-26

One Intel GPU, three jobs

An Intel Arc Pro B70 in a RHEL VM serves a local language model, transcodes for Plex and, when both are quiet, lends itself to an image model, with a small arbiter deciding who holds the card.

The card is an Intel Arc Pro B70: Battlemage, 32 GB, passed through to a RHEL VM called devastator. It was bought for one job, serving a local language model to the agents on the NanoClaw fleet. It ended up with three: the language model, Plex hardware transcodes (plus a batch campaign that re-encodes 4K remuxes over VAAPI to win back disk), and, since today, turning 3D renders into photographs.

Getting the card to show up

The driver that knows this card is xe, and the device ID has to be in it. RHEL 10.0’s kernel did not have it. The in-place upgrade from 9.6 had pinned the subscription release to 10.0, so dnf update never moved the kernel forward. Setting the release to 10.2 and updating brought in a Red Hat signed kernel with the ID backported, and after a reboot the card appeared:

Kernel driver in use: xe

along with a render node and the GuC and HuC firmware loaded from linux-firmware. The Plex container, which already mounted /dev/dri, saw the new render node without changes.

Serving a model with vLLM

vLLM runs from Intel’s llm-scaler image (intel/llm-scaler-vllm:0.14.0-b8.3.1), which talks to the card through its own oneAPI and Level Zero stack, separate from the media driver Plex uses. The served model moved up in steps: Qwen2.5-7B, then Qwen3-14B as AWQ, then a trial of Qwen3-30B-A3B.

The 30B is a mixture of experts with about 3.3B parameters active per token, so it decodes like a small model. Intel’s recipes only show it split across two or more cards, because they run it at FP16 (about 61 GB) or quantize it on the fly, which first loads the full model into host RAM. A checkpoint that is already quantized to INT4 is about 17 GB and fits one B70. It has to be GPTQ: in this image, only GPTQ checkpoints get a quantized method for the MoE layers.

Two settings mattered for the agents. The first was context. The agent harness alone sends about 16k tokens of prompt and tool schemas, so the window went to 32k, then to 64k with static YaRN on the 7B (a factor of 2 over its 32k base, the method Qwen documents). The second was tool calls. Without a parser the model returned its tool invocations as plain text; with the Hermes parser enabled they come back as real calls:

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

Leaving room for Plex

vLLM claims a fixed share of the card at start. That share went from 0.75 to 0.80 to 0.92 and settled at 0.85, which leaves about 4.8 GB for Plex: two 4K HDR transcodes at about 2 GB each plus driver headroom. A third stream falls back to the CPU. The model barely noticed; the KV cache still had room for many concurrent requests.

Lending the card out

Image generation needs most of the card, and vLLM cannot resize its memory while it runs. It reserves at start and does not shrink. So the design swaps owners instead of splitting the pool.

A recorder. Once a minute, a root timer reads every process’s DRM fdinfo, where the xe driver reports per-client VRAM and engine busy time. Clients are named by their container, or by command name, so every Plex Transcoder process counts as plex. It writes a current snapshot and a monthly history file. The history also answers an open question: Plex has hardware acceleration on this card and plenty of plays, but there was no record of how often it actually transcodes.

An arbiter. A small service keeps a queue of photo requests and a mode: llm, swapping or image. It swaps to image only when the queue is not empty, vLLM has had no running, waiting or finished request for 60 seconds, and the recorder shows no other client on the card. Then it stops vLLM, starts ComfyUI with FLUX.1 Kontext, works the queue, and hands the card back as soon as the queue is empty or 15 minutes have passed. It declares llm only after vLLM answers its health check.

A patient proxy. The NanoClaw agents reach vLLM through a small proxy. It reads the arbiter’s mode and holds requests while the mode is anything other than llm, and it retries refused connections. An agent that speaks during a swap waits instead of failing.

Measured on the first day: the swap to image plus the first photo took 85 seconds, each photo after that 52 to 62 seconds at 1328x800 and 24 steps, and vLLM was healthy again 56 seconds after handback.

What did not work

  • A mainline kernel. ELRepo’s kernel-ml knows the card, but it is unsigned, and the VM boots with Secure Boot on. The firmware rejected it before userspace. Signing it with a self-enrolled machine owner key still did not boot. It was removed; this VM runs Red Hat signed kernels only.
  • Qwen3-32B. It restarted 252 times with what looked like a VRAM problem. The kernel log said otherwise: a memory cgroup kill at 8.3 GB of RSS, which was the compose file’s memory: 8G limit. The cap went to 16G for the next attempt.
  • Resizing in place. There is no way to ask a running vLLM for memory back, which is the whole reason the arbiter exists.

What carries forward

The plan is a second B70. The two cards would form a tensor-parallel pool (TP=2, 64 GB) in a second machine, because the current host is a Mini-ITX board with one PCIe slot. Plex and the transcode campaign would then move to Arc A380 cards. Until then, the pattern holds for any shared accelerator: measure who is on it before deciding anything, and when a workload cannot shrink, trade the whole card rather than carve it.

1つのIntel GPU、3つの役割

RHEL VM 内の Intel Arc Pro B70 は、ローカルの言語モデルを提供し、Plex 用のトランスコードを担当し、両方のタスクが静かになったときは画像モデルに使用され、小さな仲裁者によってどのタスクがカードを保持するかが決まる。

この記事はローカルモデルによる機械翻訳です。原文は英語です。

このカードは、Intel Arc Pro B70: Battlemage、32 GB で、devastator と呼ばれる RHEL VM に直通しています。これはもともと 1 つの仕事のために購入され、NanoClaw フレートのエージェントにローカル言語モデルを提供するためのものでした。しかし、最終的には 3 つの用途になりました:言語モデル、Plex のハードウェアトランスコード(加えて、VAAPI を通して 4K リマックスを再エンコードするバッチキャンペーンでディスク容量を取り戻すもの)、そして今日からは 3D レンダリングを写真に変換することです。

カードを表示させるために

このカードを認識できるドライバーは xe で、デバイス ID がそれに含まれている必要があります。RHEL 10.0 のカーネルにはそれが含まれていませんでした。9.6 から 10.0 へのインプレースアップグレードにより、サブスクリプションリリースが 10.0 に固定されていたため、dnf update はカーネルを進めることがありませんでした。リリースを 10.2 に設定し、更新を実行すると、Red Hat 署名付きのカーネルが導入され、デバイス ID がバックポートされていました。再起動後、カードが表示されるようになりました:

Kernel driver in use: xe

レンダリングノードと、linux-firmwareから読み込まれたGuCおよびHuCのファームウェアとともに。Plexコンテナはすでに/dev/driをマウントしており、変更なしで新しいレンダリングノードを認識した。

vLLMを使用したモデルの提供

vLLMは、Intelのllm-scalerイメージ(intel/llm-scaler-vllm:0.14.0-b8.3.1)から実行され、独自のoneAPIおよびLevel Zeroスタックを通じてカードと通信する。これは、Plexが使用するメディアドライバとは別である。提供されたモデルは段階的に進化した:Qwen2.5-7Bから、Qwen3-14B(AWQ形式)に、そしてQwen3-30B-A3Bの試験版に。

30Bは、トークンごとに約3.3Bのパラメータがアクティブになる専門家ミックスモデルであり、小規模なモデルのようにデコードされる。Intelのレシピでは、このモデルを2枚以上のカードに分割して実行する必要があると示されている。これは、FP16(約61GB)で実行するか、リアルタイムで量子化する必要があるためである。この場合、モデル全体をホストRAMにまずロードする必要がある。すでにINT4に量子化されたチェックポイントは約17GBで、1つのB70に収まる。これはGPTQ形式でなければならない:このイメージでは、GPTQ形式のチェックポイントのみがMoEレイヤーに対して量子化された方法を取得できる。

エージェントにとって重要な設定は2つあった。1つ目はコンテキストである。エージェントハーネス自体が約16,000トークンのプロンプトおよびツールのスキーマを送信するため、ウィンドウは32,000トークンに拡張され、7Bで静的なYaRNを使用して64,000トークンに拡張された(32,000トークンのベースに対して2倍、Qwenが文書化している方法)。2つ目はツールコールである。パーサーが無効な場合、モデルはツールの呼び出しを純粋なテキストとして返す。Hermesパーサーを有効にした場合、それらは実際のコールとして返される。

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

Plex用のスペースを確保する

vLLMは起動時にカードの固定割合を確保します。この割合は0.75から0.80、0.92と変化し、最終的に0.85に落ち着き、Plexに約4.8 GBのスペースが残りました。これは、2つの4K HDRのトランスコード(各約2 GB)とドライバの余裕を考慮したものです。3つ目のストリームはCPUにフォールバックします。モデルはほとんど影響を受けませんでした。KVキャッシュには多くの同時リクエストを処理する余裕がありました。

カードを貸し出す

画像生成はカードの大部分を必要とし、vLLMは実行中にメモリを再サイズすることはできません。vLLMは起動時に確保し、縮小することはありません。そのため、設計ではプールを分割する代わりに、所有者を切り替える方法を採用しています。

レコーダー。 1分ごとにルートタイマが、各プロセスのDRM fdinfoを読み取り、xeドライバがクライアントごとのVRAMとエンジンのビジー時間を報告します。クライアントはコンテナ名またはコマンド名で識別されるため、Plex Transcoderの各プロセスはplexとしてカウントされます。現在のスナップショットと月次の履歴ファイルを書き込みます。この履歴は、あるオープンな質問にも答えることができます。Plexはこのカードでハードウェア加速が有効で、多くの再生が行われていますが、実際にトランスコードがどのくらい行われているかの記録はありませんでした。

仲裁者。 小さなサービスが、写真リクエストのキューとモード(llm、swapping、またはimage)を保持しています。キューが空でなく、vLLMが60秒間、実行中、待機中、または完了したリクエストがなく、レコーダーがカード上に他のクライアントがいないことを示している場合にのみ、モードをimageに切り替えます。その後、vLLMを停止し、FLUX.1 Kontextを使用してComfyUIを起動し、キューを処理し、キューが空になるか15分が経過した時点でカードを戻します。vLLMがヘルスチェックに応答した後にのみ、llmを宣言します。

患者代理。 NanoClawエージェントは、小さなプロキシを通じてvLLMに接続します。このプロキシは、アービターのモードを読み取り、モードがllm以外の場合はリクエストを保持し、拒否された接続を再試行します。スワップ中にエージェントが話すと、失敗する代わりに待機します。

最初の日の測定結果: スワップからimageへの切り替えと最初の写真は85秒かかり、その後の各写真は1328x800と24ステップで52〜62秒かかり、手渡し後56秒でvLLMは再び健全になりました。

うまくいかなかったこと

  • メインラインカーネル。 ELRepoのkernel-mlはカードを認識しますが、署名されておらず、Secure Bootが有効なVMで起動します。ファームウェアはユーザー空間が起動する前にこれを拒否しました。自作のマシン所有者キーで署名しても起動しませんでした。このVMは、Red Hatが署名したカーネルのみを実行します。
  • Qwen3-32B。 VRAMの問題のように見えたが、カーネルログによると、RSSが8.3GBに達した際のメモリcgroupによるキルが原因でした。これは、コンポーズファイルのmemory: 8Gの制限に一致しています。次の試行ではこの上限を16GBに引き上げました。
  • インプレースリサイズ。 実行中のvLLMにメモリを返すように要求する方法は存在せず、これはアービターが存在する理由そのものです。

今後も継続する点

計画は2台目のB70です。2枚のカードは、現在のホストがMini-ITXボードで1つのPCIeスロットしかないため、別のマシンでテンソル並列プール(TP=2、64GB)を形成します。その後、PlexとトランスコードキャンペーンはArc A380カードに移動します。それまでは、共有されたアクセラレータのパターンは変わりません: 何かを決定する前に、どのワークロードがそのアクセラレータ上にあるかを測定し、ワークロードが縮小できない場合は、カード全体を交換するのではなく、そのカードを分割して使用するのではなく、交換してください。

하나의 인텔 GPU, 세 가지 작업

RHEL 가상 머신에서 실행 중인 Intel Arc Pro B70은 로컬 언어 모델을 제공하고 Plex를 위한 트랜스코딩을 수행하며, 두 작업이 모두 일시적으로 중단될 때는 이미지 모델을 위한 작업을 수행합니다. 이 작업은 작은 중재자가 카드를 사용할 수 있는지 결정합니다.

이 글은 로컬 모델이 기계 번역한 것입니다. 원문은 영어입니다.

이 그래픽 카드는 인텔 아크 프로 B70: Battlemage, 32 GB로, 이름이 devastator인 RHEL 가상 머신에 전달되었습니다. 이 카드는 하나의 작업을 위해 구입되었는데, 이는 NanoClaw 함대에 있는 에이전트들에게 로컬 언어 모델을 제공하는 것이었습니다. 하지만 결국 세 가지 작업을 수행하게 되었죠: 언어 모델, Plex 하드웨어 트랜스코딩(그리고 VAAPI를 통해 4K 리MUX를 다시 인코딩하는 배치 캠페인으로 디스크 공간을 되찾는 작업), 그리고 오늘부터는 3D 렌더링을 사진으로 변환하는 작업입니다.

카드가 나타나도록 하기

이 카드를 인식하는 드라이버는 xe이며, 장치 ID가 포함되어 있어야 합니다. RHEL 10.0의 커널에는 이 ID가 포함되어 있지 않았습니다. 9.6에서의 인-플레이스 업그레이드는 구독 출시를 10.0에 고정시켰기 때문에 dnf update는 커널을 업데이트하지 못했습니다. 출시를 10.2로 설정하고 업데이트를 수행하면 Red Hat 서명된 커널이 포함되어 있었고, 이 커널에는 ID가 다시 추가되어 있었죠. 재부팅 후에 카드가 나타났습니다:

Kernel driver in use: xe

렌더 노드와 함께 linux-firmware에서 로드된 GuC 및 HuC 펌웨어가 포함되어 있습니다. 이미 /dev/dri을 마운트한 Plex 컨테이너는 변경 없이 새로운 렌더 노드를 인식했습니다.

vLLM을 사용한 모델 제공

vLLM은 인텔의 llm-scaler 이미지(intel/llm-scaler-vllm:0.14.0-b8.3.1)에서 실행되며, 이 이미지는 자체적인 oneAPI 및 Level Zero 스택을 통해 카드와 통신합니다. 이는 Plex가 사용하는 미디어 드라이버와 별도입니다. 제공된 모델은 단계별로 업그레이드되었습니다: Qwen2.5-7B, 그 후 Qwen3-14B로 AWQ, 그리고 Qwen3-30B-A3B의 시도까지.

30B 모델은 토큰당 약 3.3B 파라미터가 활성화된 전문가의 혼합 모델로, 소형 모델처럼 디코딩됩니다. 인텔의 레시피는 이 모델을 두 개 이상의 카드에 분산하여 실행하도록 보여주며, 이는 FP16(약 61GB)에서 실행하거나 실시간으로 양자화하는 방식으로 이루어집니다. 이 경우 먼저 전체 모델을 호스트 RAM에 로드해야 합니다. 이미 INT4로 양자화된 체크포인트는 약 17GB로, 하나의 B70에 맞습니다. 이는 GPTQ로 양자화되어야 합니다: 이 이미지에서는 GPTQ 체크포인트만 MoE 레이어에 대한 양자화 방법을 제공합니다.

에이전트에 있어 두 가지 설정이 중요했습니다. 첫 번째는 컨텍스트였습니다. 에이전트 허arness만으로 약 16k 토큰의 프롬프트 및 도구 스키마를 전송하므로, 윈도우는 32k로 증가했고, 7B에 정적 YaRN을 적용하여 64k로 증가했습니다(기본 32k 대비 2배, Qwen이 문서화한 방법). 두 번째는 도구 호출이었습니다. 파서가 없을 경우 모델은 도구 호출을 일반 텍스트로 반환하지만, Hermes 파서를 활성화하면 실제 호출로 돌아옵니다:

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

Plex을 위한 공간 확보

vLLM은 시작 시 그래픽 카드의 고정된 비율을 할당합니다. 이 비율은 0.75에서 0.80, 0.92로 증가하다가 0.85로 안정화되어, Plex을 위한 약 4.8 GB의 공간이 남게 됩니다. 이는 각각 약 2 GB씩 소요되는 두 개의 4K HDR 변환 작업과 드라이버의 여유 공간을 고려한 것입니다. 세 번째 스트림은 CPU로 전환됩니다. 모델은 거의 영향을 받지 않았으며, KV 캐시는 여전히 많은 동시 요청을 처리할 수 있는 여유 공간이 있었습니다.

그래픽 카드 대여

이미지 생성은 그래픽 카드의 대부분을 사용하며, vLLM은 실행 중일 때 메모리를 재조정할 수 없습니다. 시작 시에만 할당되고 줄일 수 없습니다. 따라서, 풀을 나누는 대신 소유권을 교환하는 방식으로 설계되었습니다.

기록 장치. 매분, 루트 타이머는 모든 프로세스의 DRM fdinfo를 읽습니다. 여기서 xe 드라이버는 클라이언트별 VRAM 및 엔진 사용 시간을 보고합니다. 클라이언트는 컨테이너 이름이나 명령 이름으로 식별되므로, 각 Plex Transcoder 프로세스는 plex로 간주됩니다. 이는 현재 스냅샷과 월별 기록 파일을 작성합니다. 기록 파일은 여전히 미해결의 질문에 답을 제공합니다: Plex은 이 그래픽 카드에서 하드웨어 가속이 활성화되어 있고, 많은 재생이 이루어지고 있지만, 실제로 얼마나 자주 변환 작업을 수행하는지는 기록되어 있지 않았습니다.

중재자. 작은 서비스는 사진 요청의 대기열과 모드(llm, swapping 또는 image)를 유지합니다. 대기열이 비어 있고, vLLM이 60초 동안 실행, 대기 또는 완료된 요청이 없으며, 기록 장치가 카드에 다른 클라이언트가 없는 것을 보고할 때만 image 모드로 전환합니다. 그런 다음 vLLM을 중지하고, FLUX.1 Kontext를 사용한 ComfyUI를 시작합니다. 대기열을 처리한 후, 대기열이 빈 경우나 15분이 지나면 카드를 다시 돌려줍니다. vLLM이 건강 상태 검사를 통과한 후에만 llm 상태로 선언됩니다.

환자 대리자. NanoClaw 에이전트는 vLLM 에 도달하기 위해 작은 프록시를 사용합니다. 이 프록시는 아르비터의 모드를 읽고, 모드가 llm 이 아닐 때 요청을 유지하며, 거부된 연결을 재시도합니다. 스왑 중에 말하는 에이전트는 실패하기보다 대기합니다.

첫날 측정 결과: image 로의 스왑과 첫 번째 사진은 85초가 걸렸고, 이후 각 사진은 1328x800 해상도와 24단계에서 52~62초가 걸렸으며, vLLM 은 핸드백 후 56초 만에 다시 건강해졌습니다.

작동하지 않은 사항

  • 메인 라인 커널. ELRepo의 kernel-ml은 카드를 인식하지만 서명되지 않았고, VM은 Secure Boot가 켜져 있습니다. 커널은 사용자 공간이 실행되기 전에 펌웨어에 의해 거부되었습니다. 자체 등록된 머신 소유자 키로 서명해도 부팅되지 않았습니다. 이 VM은 이제 Red Hat 서명된 커널만 실행합니다.
  • Qwen3-32B. 이 모델은 VRAM 문제로 보이는 듯한 이유로 252회 재시작되었습니다. 커널 로그는 다르게 말했습니다: RSS가 8.3GB에 달했을 때 메모리 cgroup이 종료되었습니다. 이는 구성 파일의 memory: 8G 제한이었습니다. 다음 시도에서는 이 제한을 16GB으로 높였습니다.
  • 위치에서의 크기 조정. 실행 중인 vLLM 에게 메모리 반환을 요청할 방법이 없어, 이는 아르비터가 존재하는 이유입니다.

앞으로 이어지는 사항

계획은 두 번째 B70입니다. 두 카드는 현재 호스트가 Mini-ITX 보드로 PCIe 슬롯이 하나뿐이기 때문에, 두 번째 머신에서 텐서 병렬 풀(TP=2, 64GB)을 형성할 것입니다. 그 후 Plex 및 트랜스코딩 캠페인은 Arc A380 카드로 이전할 것입니다. 그때까지 공유 가속기의 패턴은 다음과 같습니다: 무엇이든 결정하기 전에 가속기 사용 상태를 측정하고, 작업 부하가 축소할 수 없는 경우 전체 카드를 교체하는 것이 더 나은 선택입니다.

一块 Intel GPU,三个任务

一个 Intel Arc Pro B70 在 RHEL 虚拟机中运行,为本地语言模型提供服务,为 Plex 进行转码,并且当两者都空闲时,它会用于图像模型,一个小的仲裁者决定谁使用这张卡。

本文由本地模型机器翻译,原文为英文。

这张显卡是 Intel Arc Pro B70: Battlemage,32 GB,通过直通方式分配给了名为 devastator 的 RHEL 虚拟机。它最初是为一个任务购买的,即为 NanoClaw 队列上的代理提供本地语言模型服务。结果它却承担了三个任务:语言模型、Plex 硬件转码(还有一个批量活动通过 VAAPI 将 4K 重新封装的视频重新编码以节省磁盘空间),以及从今天起,将 3D 渲染图像转换为照片。

让显卡显示出来

了解这张显卡的驱动程序是 xe,并且设备 ID 必须包含在其中。RHEL 10.0 的内核中没有这个 ID。从 9.6 升级时,订阅版本被固定为 10.0,因此 dnf update 没有将内核向前推进。将版本设置为 10.2 并更新后,引入了一个带有回溯设备 ID 的 Red Hat 签名内核,重启后显卡就出现了:

Kernel driver in use: xe

与渲染节点一起,从 linux-firmware 加载了 GuC 和 HuC 固件。Plex 容器已经挂载了 /dev/dri,在没有更改的情况下看到了新的渲染节点。

使用 vLLM 提供模型服务

vLLM 从 Intel 的 llm-scaler 镜像(intel/llm-scaler-vllm:0.14.0-b8.3.1)运行,它通过自己的 oneAPI 和 Level Zero 堆栈与显卡通信,这与 Plex 使用的媒体驱动程序是分开的。提供的模型逐步升级:Qwen2.5-7B,然后是 Qwen3-14B(AWQ 版本),接着是 Qwen3-30B-A3B 的测试。

30B 是一个专家混合模型,每个 token 激活约 3.3B 个参数,因此它像一个小模型一样进行解码。Intel 的方案只显示它分布在两个或更多的卡上,因为它们以 FP16(约 61 GB)运行,或者在运行时进行量化,这首先会将完整的模型加载到主机内存中。已经量化为 INT4 的检查点大约是 17 GB,适合一个 B70。它必须使用 GPTQ:在这个镜像中,只有 GPTQ 检查点对 MoE 层使用量化方法。

对于代理来说,有两个设置很重要。第一个是上下文。代理框架本身发送大约 16k 个 token 的提示和工具模式,因此窗口扩展到了 32k,然后在 7B 上使用静态 YaRN 扩展到了 64k(比其 32k 基础增加了 2 倍,这是 Qwen 文档中提到的方法)。第二个是工具调用。在没有解析器的情况下,模型会以纯文本形式返回其工具调用;启用 Hermes 解析器后,它们会以真正的调用形式返回:

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

为 Plex 留出空间

vLLM 在启动时会占用显卡的固定份额。这个份额从 0.75 增加到 0.80,再到 0.92,最终稳定在 0.85,这样就为 Plex 留出了大约 4.8 GB 的空间:两个 4K HDR 转码任务,每个大约需要 2 GB,再加上一些驱动程序的余量。第三个流则会回退到 CPU。模型几乎没察觉到这一点;KV 缓存仍然有足够的空间处理许多并发请求。

将显卡借出

图像生成需要使用大部分显卡资源,而 vLLM 在运行时无法调整其内存大小。它在启动时预留资源,且不会减少。因此,设计上采用的是交换拥有者的方式,而不是分割资源池。

一个记录器。 每一分钟,一个根计时器会读取每个进程的 DRM fdinfo,其中 xe 驱动程序会报告每个客户端的 VRAM 使用情况和引擎忙碌时间。客户端通过其容器名称或命令名称来命名,因此每个 Plex Transcoder 进程都会被计为 plex。它会写入当前快照和一个每月的历史文件。历史文件还回答了一个开放性问题:Plex 在这张显卡上启用了硬件加速,并且有大量播放,但之前没有记录它实际进行转码的频率。

一个仲裁器。 一个小型服务维护一个照片请求队列和一个模式:llm、swapping 或 image。只有当队列不为空,vLLM 已经有 60 秒没有运行、等待或完成任何请求,并且记录器显示显卡上没有其他客户端时,它才会切换到 image 模式。然后它停止 vLLM,启动 ComfyUI 并加载 FLUX.1 Kontext,处理队列中的请求,一旦队列为空或 15 分钟已过,就将显卡交还。只有在 vLLM 通过健康检查后,它才会声明 llm。

一个患者代理。 NanoClaw 代理通过一个小的代理与 vLLM 通信。它读取仲裁器的模式,并在模式不是 llm 时保持请求,同时重试被拒绝的连接。在交换过程中,如果代理需要发言,它会等待而不是失败。

第一天测量的结果:交换到 image 加上第一张照片耗时 85 秒,之后每张照片在 1328x800 和 24 步的情况下耗时 52 到 62 秒,而 vLLM 在交接后 56 秒内恢复健康。

未成功的工作

  • 主线内核。 ELRepo 的 kernel-ml 能识别该显卡,但它是未签名的,而虚拟机启用了 Secure Boot。固件在用户空间之前就拒绝了它。即使使用自注册的机器所有者密钥进行签名,也无法启动。因此,它被移除了;这个虚拟机只运行 Red Hat 签名的内核。
  • Qwen3-32B。 它看起来像是显存问题,重启了 252 次。内核日志显示不同:在 RSS 达到 8.3 GB 时,内存 cgroup 杀掉了进程,这正好是 compose 文件中设置的 memory: 8G 限制。下一次尝试时,限制提升到了 16GB。
  • 原地调整大小。 没有办法向正在运行的 vLLM 请求释放内存,而这正是仲裁器存在的全部原因。

前进的方向

计划是使用第二个 B70。两个显卡将在第二台机器中组成一个张量并行池(TP=2,64GB),因为当前主机是 Mini-ITX 板,只有一个 PCIe 插槽。Plex 和转码任务将转移到 Arc A380 显卡上。在此之前,对于任何共享的加速器,模式依然适用:在决定任何事情之前,先测量谁在使用它,当工作负载无法缩小的时候,应该交换整个显卡而不是分割使用它。

Una GPU de Intel, tres tareas

Una tarjeta gráfica Intel Arc Pro B70 en un VM de RHEL sirve un modelo de lenguaje local, transcodifica para Plex y, cuando ambos están inactivos, se utiliza para un modelo de imágenes, con un pequeño árbitro que decide quién posee la tarjeta.

Este artículo es una traducción automática hecha por un modelo local. El original está en inglés.

La tarjeta es una Intel Arc Pro B70: Battlemage, 32 GB, pasada a una VM de RHEL llamada devastator. Fue comprada para un trabajo: servir un modelo de lenguaje local a los agentes en la flota NanoClaw. Al final terminó con tres: el modelo de lenguaje, transcodificación de hardware de Plex (más una campaña en lote que re-encodifica remuxes de 4K sobre VAAPI para recuperar espacio en disco), y, desde hoy, convertir renders 3D en fotografías.

Haciendo que la tarjeta aparezca

El controlador que conoce esta tarjeta es xe, y el ID del dispositivo tiene que estar en él. El kernel de RHEL 10.0 no lo tenía. La actualización en lugar de la actualización desde 9.6 había fijado la versión de lanzamiento de la suscripción a 10.0, por lo que dnf update nunca avanzó el kernel. Establecer la versión de lanzamiento a 10.2 y actualizar trajo un kernel firmado por Red Hat con el ID retrotraído, y después de un reinicio la tarjeta apareció:

Kernel driver in use: xe

junto con un nodo de renderizado y el firmware GuC y HuC cargado desde linux-firmware. El contenedor de Plex, que ya montó /dev/dri, vio el nuevo nodo de renderizado sin cambios.

Servir un modelo con vLLM

vLLM se ejecuta desde la imagen llm-scaler de Intel (intel/llm-scaler-vllm:0.14.0-b8.3.1), que se comunica con la tarjeta a través de su propia pila oneAPI y Level Zero, independiente del controlador de medios que usa Plex. El modelo servido avanzó en pasos: Qwen2.5-7B, luego Qwen3-14B como AWQ, y luego una prueba de Qwen3-30B-A3B.

El 30B es un modelo de mezcla de expertos con aproximadamente 3.3B parámetros activos por token, por lo que se decodifica como un modelo pequeño. Las recetas de Intel solo muestran que se divide entre dos o más tarjetas, ya que se ejecuta en FP16 (aproximadamente 61 GB) o se cuantiza en tiempo real, lo cual carga primero el modelo completo en la memoria RAM del host. Un checkpoint ya cuantizado a INT4 es aproximadamente de 17 GB y cabe en un B70. Tiene que ser GPTQ: en esta imagen, solo los checkpoints GPTQ obtienen un método de cuantización para las capas de MoE.

Dos configuraciones importaron para los agentes. La primera fue el contexto. El propio harness del agente envía aproximadamente 16k tokens de prompt y esquemas de herramientas, por lo que la ventana se llevó a 32k, y luego a 64k con YaRN estático en el 7B (un factor de 2 sobre su base de 32k, el método que documenta Qwen). La segunda fue las llamadas a herramientas. Sin un analizador, el modelo devolvió sus invocaciones de herramientas como texto plano; con el analizador Hermes habilitado, regresan como llamadas reales:

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

Dejando espacio para Plex

vLLM reclama una porción fija de la tarjeta al iniciar. Esa porción pasó de 0.75 a 0.80 a 0.92 y finalmente se estabilizó en 0.85, lo que deja aproximadamente 4.8 GB para Plex: dos transcodificaciones de 4K HDR a unos 2 GB cada una más un margen para el controlador. Un tercer flujo recurre al CPU. El modelo apenas lo notó; aún había espacio en la caché KV para muchas solicitudes concurrentes.

Prestar la tarjeta

La generación de imágenes requiere la mayor parte de la tarjeta, y vLLM no puede redimensionar su memoria mientras se ejecuta. Reserva al iniciar y no se reduce. Por lo tanto, el diseño intercambia dueños en lugar de dividir el pool.

Un grabador. Cada minuto, un temporizador raíz lee el DRM fdinfo de cada proceso, donde el xe controlador reporta VRAM por cliente y tiempo de uso de la CPU. Los clientes se nombran según su contenedor, o según el nombre del comando, por lo tanto, cada proceso de transcodificación de Plex cuenta como plex. Escribe una captura actual y un archivo de historia mensual. La historia también responde a una pregunta abierta: Plex tiene aceleración hardware en esta tarjeta y muchas reproducciones, pero no había registro de cuántas veces realmente transcodifica.

Un árbitro. Un pequeño servicio mantiene una cola de solicitudes de fotos y un modo: llm, swapping o image. Se cambia a image solo cuando la cola no esté vacía, vLLM no haya tenido ninguna solicitud en ejecución, esperando o finalizada durante 60 segundos, y el grabador muestre que no hay otro cliente en la tarjeta. Luego detiene vLLM, inicia ComfyUI con FLUX.1 Kontext, procesa la cola y devuelve la tarjeta tan pronto como la cola esté vacía o hayan pasado 15 minutos. Declara llm solo después de que vLLM responda a su prueba de salud.

Un proxy de paciente. Los agentes NanoClaw alcanzan a vLLM a través de un pequeño proxy. Éste lee el modo del árbitro y mantiene las solicitudes mientras el modo no es llm, y vuelve a intentar las conexiones rechazadas. Un agente que habla durante un intercambio espera en lugar de fallar.

Medido el primer día: el intercambio a image más la primera foto tomó 85 segundos, cada foto después de eso 52 a 62 segundos a 1328x800 y 24 pasos, y vLLM estuvo nuevamente saludable 56 segundos después de la devolución.

Lo que no funcionó

  • Un núcleo principal. El kernel-ml de ELRepo reconoce la tarjeta, pero está sin firmar, y la VM inicia con Secure Boot activado. El firmware lo rechazó antes de que se cargara el espacio de usuario. Incluso firmarlo con una clave de propietario de la máquina autoregistrada no permitió el arranque. Fue eliminado; esta VM solo ejecuta núcleos firmados por Red Hat.
  • Qwen3-32B. Se reinició 252 veces con lo que parecía un problema de VRAM. El registro del núcleo decía lo contrario: un asesinato de grupo de memoria de cgroups a 8,3 GB de RSS, que era el límite de memory: 8G del archivo de configuración. El límite se aumentó a 16 GB para el siguiente intento.
  • Redimensionamiento en lugar. No hay forma de pedirle a un vLLM en ejecución que devuelva memoria, lo cual es la razón principal de la existencia del árbitro.

Lo que se lleva adelante

El plan es un segundo B70. Las dos tarjetas formarían una piscina de paralelismo de tensores (TP=2, 64 GB) en una segunda máquina, ya que la host actual es una placa Mini-ITX con un solo slot PCIe. Plex y la campaña de transcodificación se moverían a las tarjetas Arc A380. Hasta entonces, el patrón se mantiene para cualquier acelerador compartido: mide quién está en él antes de decidir algo, y cuando una carga de trabajo no pueda reducirse, intercambia toda la tarjeta en lugar de dividirla.

Eine Intel-GPU, drei Aufgaben

Eine Intel Arc Pro B70 in einem RHEL-VM dient einem lokalen Sprachmodell, transcodiert für Plex und, wenn beide ruhig sind, wird sie für ein Bildmodell genutzt, wobei ein kleiner Schiedsrichter entscheidet, wer die Karte hat.

Dieser Beitrag ist eine maschinelle Übersetzung durch ein lokales Modell. Das Original ist auf Englisch.

Die Grafikkarte ist eine Intel Arc Pro B70: Battlemage, 32 GB, die an ein RHEL-VM namens devastator weitergeleitet wird. Sie wurde für eine Aufgabe gekauft, um einem lokalen Sprachmodell auf der NanoClaw-Flotte Agenten zu dienen. Sie endete mit drei: das Sprachmodell, Plex-Hardware-Transkodierung (plus einer Kampagne, die 4K-Remuxes über VAAPI neu kodiert, um Speicherplatz zurückzugewinnen), und seit heute, 3D-Rendern in Fotos umzuwandeln.

Die Karte zum Erscheinen bringen

Der Treiber, der diese Karte kennt, ist xe, und die Geräte-ID muss darin enthalten sein. Der Kernel von RHEL 10.0 hatte sie nicht. Das In-Place-Upgrade von 9.6 hatte die Abonnement-Release auf 10.0 festgelegt, also bewegte sich dnf update den Kernel nie weiter. Das Festlegen des Releases auf 10.2 und das Aktualisieren brachten einen von Red Hat signierten Kernel mit der ID zurückportiert, und nach einem Neustart erschien die Karte:

Kernel driver in use: xe

zusammen mit einem Render-Node und den GuC- und HuC-Firmware, die von linux-firmware geladen werden. Der Plex-Container, der bereits /dev/dri gemountet hatte, erkannte den neuen Render-Node ohne Änderungen.

Ein Modell mit vLLM bereitstellen

vLLM läuft vom Intel llm-scaler-Image (intel/llm-scaler-vllm:0.14.0-b8.3.1) aus, das über seine eigene oneAPI- und Level Zero-Stack mit der Grafikkarte kommuniziert, getrennt vom Medien-Treiber, den Plex verwendet. Das bereitgestellte Modell wurde in Schritten weiterentwickelt: Qwen2.5-7B, dann Qwen3-14B als AWQ, gefolgt von einem Test mit Qwen3-30B-A3B.

Die 30B ist ein Mischung aus Experten mit etwa 3,3B Parametern aktiv pro Token, sodass sie sich wie ein kleines Modell decodiert. Intels Rezepte zeigen es nur über zwei oder mehr Karten verteilt, da sie es in FP16 (etwa 61 GB) laufen lassen oder es in Echtzeit quantisieren, was zunächst das gesamte Modell in den Host-RAM lädt. Ein bereits auf INT4 quantisiertes Checkpoint ist etwa 17 GB groß und passt in einen B70. Es muss GPTQ sein: in diesem Image erhalten nur GPTQ-Checkpoints eine quantisierte Methode für die MoE-Schichten.

Für die Agenten waren zwei Einstellungen wichtig. Die erste war der Kontext. Allein das Agenten-Setup sendet etwa 16k Tokens von Prompt und Tool-Schemata, sodass das Fenster auf 32k, dann auf 64k mit statischem YaRN auf dem 7B (ein Faktor von 2 über seine 32k Basis, die Methode, die Qwen dokumentiert) erhöht wurde. Die zweite Einstellung war die Tool-Aufrufe. Ohne Parser gab das Modell seine Tool-Aufrufe als reinen Text zurück; mit dem aktivierten Hermes-Parser kamen sie als echte Aufrufe zurück:

- --enable-auto-tool-choice
- --tool-call-parser
- hermes

Platz für Plex lassen

vLLM beanspricht zu Startzeit einen festen Anteil der Grafikkarte. Dieser Anteil ging von 0,75 über 0,80 und 0,92 bis zu 0,85, was ungefähr 4,8 GB für Plex lässt: zwei 4K HDR-Transkodierungen mit jeweils etwa 2 GB plus Spielraum für den Treiber. Ein dritter Stream fällt auf die CPU zurück. Das Modell bemerkte dies kaum; der KV-Cache hatte immer noch Platz für viele parallele Anfragen.

Die Grafikkarte weitergeben

Bildgenerierung benötigt den Großteil der Grafikkarte, und vLLM kann während des Betriebs seinen Speicher nicht verkleinern. Es reserviert zu Startzeit und verkleinert sich nicht. Daher wechselt das Design die Nutzung statt den Pool zu teilen.

Ein Aufzeichner. Alle 60 Sekunden liest ein Root-Timer die DRM fdinfo aller Prozesse, wo der xe Treiber pro Client VRAM und die Zeit, in der der Engine beschäftigt ist, meldet. Clients werden nach ihrem Container benannt oder nach dem Befehlsnamen, daher zählt jeder Plex Transcoder-Prozess als plex. Er schreibt einen aktuellen Snapshot und eine monatliche Historie-Datei. Die Historie beantwortet auch eine offene Frage: Plex hat auf dieser Grafikkarte Hardwarebeschleunigung und viele Wiedergaben, aber es gab keine Aufzeichnung, wie oft es tatsächlich transkodierte.

Ein Schlichter. Ein kleiner Dienst verwaltet eine Warteschlange für Fotobegehren und einen Modus: llm, swapping oder image. Er wechselt erst zu image, wenn die Warteschlange nicht leer ist, vLLM seit 60 Sekunden keine laufenden, wartenden oder abgeschlossenen Anfragen hatte und der Aufzeichner keine anderen Clients auf der Grafikkarte anzeigt. Dann stoppt er vLLM, startet ComfyUI mit FLUX.1 Kontext, bearbeitet die Warteschlange und gibt die Grafikkarte zurück, sobald die Warteschlange leer ist oder 15 Minuten vergangen sind. Er erklärt llm erst, nachdem vLLM auf seine Gesundheitsprüfung reagiert hat.

Ein Patientenproxy. Die NanoClaw-Agenten erreichen vLLM über einen kleinen Proxy. Dieser liest den Modus des Arbiters und hält Anfragen an, solange der Modus nicht llm ist, und versucht, abgelehnte Verbindungen erneut herzustellen. Ein Agent, der während eines Wechsels spricht, wartet stattdessen, anstatt zu scheitern.

Gemessen am ersten Tag: der Wechsel zu image plus das erste Foto dauerte 85 Sekunden, jedes Foto danach 52 bis 62 Sekunden bei 1328x800 und 24 Schritten, und vLLM war 56 Sekunden nach der Rückgabe wieder gesund.

Was nicht funktioniert hat

  • Ein Mainline-Kernel. Der ELRepo-Kernel-ml erkennt die Grafikkarte, ist aber nicht signiert, und die VM startet mit Secure Boot. Die Firmware lehnte es ab, bevor der Userspace geladen wurde. Selbst mit einer selbst eingerichteten Maschinenbesitzer-Schlüssel-Signatur startete sie nicht. Sie wurde entfernt; diese VM läuft nur mit signierten Kernen von Red Hat.
  • Qwen3-32B. Es wurde 252 Mal neu gestartet, was wie ein VRAM-Problem aussah. Der Kernel-Log sagte etwas anderes: ein Speicher cgroup Kill bei 8,3 GB RSS, was der memory: 8G Grenze im Kompositionsdatei entsprach. Die Grenze wurde für den nächsten Versuch auf 16 GB erhöht.
  • In-Place-Resizing. Es gibt keine Möglichkeit, einem laufenden vLLM Speicher zurückzugeben, was der Grund dafür ist, dass der Arbiter existiert.

Was weitergeführt wird

Der Plan ist ein zweiter B70. Die beiden Karten würden in einem zweiten Rechner einen Tensor-Parallel-Pool (TP=2, 64 GB) bilden, da der aktuelle Host eine Mini-ITX-Platte mit nur einem PCIe-Slot ist. Plex und der Transcode-Kampf würden dann auf Arc A380-Karten wechseln. Bis dahin gilt das Muster für jede gemeinsam genutzte Beschleunigungskarte: messen, wer darauf ist, bevor man etwas entscheidet, und wenn eine Arbeitslast nicht kleiner werden kann, tausche die ganze Karte anstelle davon, sie zu teilen.