Intel Arc Pro B50 (16 GB) for Ollama / AI on TrueNAS – Feasible or Not?

Great post. I have a B580 and set everything up according to the Intel instructions within a VM passed through, and then installed everything else through here using Docker compose on a Ubuntu LTS VM (search eleiton/ollama-intel-arc on GitHub)

For anyone who is having trouble, make sure you update your BIOS to the latest firmware. I spent four days running around in circles because while TrueNAS could see my device as having Resizable BAR, the VM refused to see it (and also refused to boot through UEFI, using CSM instead). After updating my BIOS it worked. (MSI B560M A PRO, Intel i7 11700K, 32 GB DDR4, Intel Arc B580).

I would have liked to be able to share the GPU with the rest of my TrueNAS apps that are running on the host, but oh well.

Hi all,

As of today everything seems to be working and well I should add.

I can run Ollama (through portainer) using Vulkan with almost no modifications and I have Qwen 3.5:9B Running at 15.69T/s working on some optimization. Googles Gemma seems to not get any prompt and is a bit broken on Vulkan ATM but most other things work!

1 Like

Quick update from my original post — I was able to get the Arc Pro B50 working for hardware transcoding on TrueNAS SCALE, so I wanted to share what actually worked.

Short version: it does work, but only with the right setup.

One important note up front:
I am running TrueNAS SCALE 26.0.0-BETA.1. Based on earlier testing and what others have reported, support for Battlemage GPUs depends heavily on newer kernel + xe driver support, which appears to be improved in this beta.

Also worth noting:
I am running Tdarr via Docker Compose, not as an ix-app. This gives full control over device mapping and environment configuration.

What worked for me:

  • Running Tdarr in Docker Compose on the SCALE host, no VM
  • Using QSV / oneVPL, not VAAPI as the primary path
  • Explicitly targeting the Battlemage render node:
    • /dev/dri/renderD129
  • My GPU mapping is:
    • Intel UHD 770 iGPU → /dev/dri/renderD128
    • Intel Arc Pro B50 / Battlemage → /dev/dri/renderD129

The key FFmpeg option was:

bash -qsv_device /dev/dri/renderD129

That allowed QSV to bind to the B50 instead of the iGPU.

Validation:

  • vainfo shows hardware encode support, including HEVC and AV1 profiles
  • FFmpeg hevc_qsv encode works when explicitly pointed at /dev/dri/renderD129
  • Tdarr GPU worker is active
  • /sys/kernel/debug/dri/1/clients showed the active ffmpeg process on dev 129
  • /sys/kernel/debug/dri/0/clients did not show the active test process during the B50 run
  • The iGPU stayed idle during the B50-targeted QSV test

Real-world performance:

  • Around 330–370 FPS on 1080p H.264 to HEVC jobs
  • In my Tdarr workload, the B50/QSV path is matching or beating my RTX 4070/NVENC node while using less power

Important correction from my earlier assumptions:

I originally thought VAAPI would be the better path for the B50. After testing, QSV via oneVPL is working correctly on the B50 when explicitly pinned with -qsv_device /dev/dri/renderD129.

Monitoring note:

intel_gpu_top detects the B50 as card1, but engine monitoring does not currently work correctly for the B50 on my setup with the xe driver. The better validation method was checking DRM clients under:

bash /sys/kernel/debug/dri/1/clients

Thermals are visible through sensors under xe-pci-0300, including package temp, VRAM temp, and fan RPM.

Conclusion:

The B50 is usable for transcoding on TrueNAS SCALE without a VM. In my setup, the winning path is Docker Compose + explicit QSV device binding to /dev/dri/renderD129. It is not fully plug-and-play, but once pinned correctly, it performs extremely well.

Thermals also look good under sustained Tdarr load. The card is reporting through sensors as xe-pci-0300:

text fan1: 2794 RPM pkg: +64.0°C vram: +62.0°C cap: 70.00 W

So the B50 is not just working; it is staying cool and power-limited while running real transcode jobs.

1 Like

“Above 4G decoding” and “resizable BAR” needs to be enabled in BIOS. If the latest BIOS doesn’t have that, the sane option is to stop and not use a B series card on that board.

The Mad Science option is to add resizable BAR to the BIOS - but that obviously risks bricking the entire system without hope of recovery. GitHub - xCuri0/ReBarUEFI: Resizable BAR for (almost) any UEFI system · GitHub

Short note on what resizable BAR is: When the PCIe spec was written, 32-bit CPUs could address 4G of memory space total. So in order for the CPU to access the memory on a GPU, it was given a 256MB window, the Base Address Register. On the GPU side, that window can “slide” over the full RAM of the GPU.

NVidia GPUs are good at this, put a lot of extra transistors in for DMA and the like to make it suck less, and take a 5-15% performance hit. Intel GPUs were built with 64-bit systems in mind, and take a 50% performance hit or, on Linux, don’t work at all. Particularly B series. A310 used only for transcode works even without resizable BAR, though it’d also benefit from having it. A310 also takes a less drastic performance hit.

With 64-bit CPUs, the option to resize the BAR to the full size of the GPU memory and place it way above 4G was added. But the BIOS has to expose that. “Above 4G decoding” and “resizable BAR” means this BAR is in high memory, above the max RAM the board can take, often at 128GB. And sized to address the entire GPU at once … well, again depending on BIOS. Some BIOS versions have limits: <4GB, <16GB, <64GB. Ideally, the BAR size is unlimited.

2 Likes

Thanks for the update!

Interesting this seems not to be working on the normal Jellyfin transcoding options for me but I also cant validate it since intel_gpu_top is also broken for me :frowning: and running vainfo returns:

error: XDG_RUNTIME_DIR is invalid or not set in the environment.
error: can't connect to X server!
libva info: VA-API version 1.20.0
libva info: Trying to open /usr/lib/x86_64-linux-gnu/dri/xe_drv_video.so
libva info: va_openDriver() returns -1
vaInitialize failed with error code -1 (unknown libva error),exit

Anyway I dont use Jellyfin that much and am interested more in getting Ollama and Immich as well as piper and whisper going but one I am a bit confused on why intel_gpu_top is broken it returns: No device filter specified and no discrete/integrated i915 devices found in both TrueNAS shell and docker containers wondering if you did anything to get that to work?

I got it working with a new mobo after trying the repo you showed ended up needing to put a contact clip over the BIOS chip and flash and change the BIOS manually but it bricked the mobo lol. Nonetheless Interesting context thanks for sharing this!

1 Like

Yep bricking the thing entirely is absolutely one of the risks of trying to roll your own BIOS.

2 Likes

One more follow-up since @Trotsky mentioned intel_gpu_top and vainfo.

I would not treat intel_gpu_top as the source of truth for the B50 right now. On my setup, intel_gpu_top sees the card as card1, but engine monitoring is not reliable with the B50/xe path yet. That is why I was validating the actual workload through DRM clients instead.

For me, the better checks were:

ls -l /dev/dri

Confirm which render node is the B50. In my case:

Intel UHD 770 iGPU        -> /dev/dri/renderD128
Intel Arc Pro B50 / xe    -> /dev/dri/renderD129

Then test the B50 directly instead of letting tools auto-pick the wrong device:

vainfo --display drm --device /dev/dri/renderD129

The XDG_RUNTIME_DIR is invalid or not set and can't connect to X server messages are not necessarily fatal by themselves on a headless server. The important part is whether it successfully falls through to DRM and loads the driver for the render node. If it never gets a valid DRM result, then it is a real problem.

For FFmpeg/QSV testing, the key for me was explicitly pinning the B50:

ffmpeg \
  -qsv_device /dev/dri/renderD129 \
  -hwaccel qsv \
  -hwaccel_output_format qsv \
  -i input.mkv \
  -c:v hevc_qsv \
  -global_quality 23 \
  -look_ahead 1 \
  -c:a copy \
  output.mkv

While that is running, I checked the kernel DRM client list:

cat /sys/kernel/debug/dri/1/clients

On my system, dri/1 corresponds to the B50. If the running ffmpeg process shows up there, that is much better evidence than intel_gpu_top right now.

For Jellyfin specifically, I suspect the issue is that Jellyfin is either:

  1. not being given the right render node,
  2. defaulting to the iGPU,
  3. trying VAAPI first instead of QSV,
  4. or using bundled FFmpeg/libva behavior that does not line up cleanly with the B50/xe path yet.

If Jellyfin exposes a QSV device field, I would try setting it explicitly to:

/dev/dri/renderD129

If it only works through VAAPI, then I would test VAAPI separately with:

vainfo --display drm --device /dev/dri/renderD129

But for my Tdarr testing, QSV/oneVPL was the winning path, not VAAPI. The main lesson from my setup is: do not trust auto-detection with both an Intel iGPU and a B50 installed. Pin the render node directly and then validate by checking which DRM device the active process is attached to.

Small Immich follow-up.

I now have better evidence that Immich ML is not just seeing the B50, but actually opening the B50 render node through OpenVINO.

Inside the Immich ML container:

docker exec -it immich_machine_learning ls -l /dev/dri
docker exec -it immich_machine_learning env | grep -i -E 'openvino|immich|device|gpu'

Output:

total 0
crw-rw---- 1 root video 226,   1 May  4 15:02 card1
crw-rw---- 1 root   107 226, 129 May  4 15:02 renderD129

IMMICH_LOG_LEVEL=log
DEVICE=openvino
IMMICH_BUILD_IMAGE=v2.7.5
IMMICH_SOURCE_REF=v2.7.5

On my system, /dev/dri/renderD129 is the Arc Pro B50. The Immich ML container is only being given the B50 render node, not the UHD 770 iGPU render node.

Then on the TrueNAS host:

cat /sys/kernel/debug/dri/1/clients

Output:

             command  tgid dev master a   uid      magic                                                             name                   id
                Xvnc 2695312 129   n    n     0          0                                                          <unset>               115625
              python 2661109 129   n    n     0          0                                                          <unset>               160581

I then tied that Python process back to Immich ML:

ps -fp 2661109
docker inspect -f '{{.State.Pid}} {{.Name}}' immich_machine_learning

Output:

UID          PID    PPID  C STIME TTY          TIME CMD
root     2661109 2659213  0 May04 ?        00:06:10 python -m gunicorn immich_ml.main:app -k immich_ml.config.CustomUvicornWorker -c /usr/src/immich_ml/gunicorn_conf.py -b [::]:3003 -w 1 -t 300 --log

2653917 /immich_machine_learning

So the current status from my side is now:

B50 + TrueNAS SCALE 26.0.0-BETA.1 + Docker Compose + Tdarr/QSV: confirmed working
B50 + Immich ML container + OpenVINO + renderD129: confirmed opening the B50 render node
B50 + Ollama: still not tested by me yet

I am still being careful not to claim that every Immich ML task is accelerated until I do more job-level testing or benchmarking, but this is no longer just “the container can see the device.” Immich ML/OpenVINO is opening the B50 render node on the TrueNAS host.

Interesting for some reason my when I run the TrueNAS commads I get nothing:

sudo cat /sys/kernel/debug/dri/128/clients
             command  tgid dev master a   uid      magic                                                             name                   id
 sudo cat /sys/kernel/debug/dri/0/clients
             command  tgid dev master a   uid      magic                                                             name                   id
 sudo cat /sys/kernel/debug/dri/0000:2d:00.0/clients
             command  tgid dev master a   uid      magic                                                             name                   id

and the Immich commands:

I have no name!@4c757f631964:/usr/src$ ls -l /dev/dri
total 0
crw-rw---- 1 root video 226, 0 May 11 08:22 card0
I have no name!@4c757f631964:/usr/src$ env | grep -i -E ‘openvino|immich|device|gpu’
NVIDIA_VISIBLE_DEVICES=void
IMMICH_SOURCE_REF=v2.7.5
IMMICH_BUILD=24350167851
IMMICH_SOURCE_COMMIT=95e57a24cb11b4bcff39b770ae2d81443434c210
IMMICH_PORT=32002
IMMICH_LOG_LEVEL=log
IMMICH_SOURCE_URL=``https://github.com/immich-app/immich/commit/95e57a24cb11b4bcff39b770ae2d81443434c210
IMMICH_REPOSITORY=immich-app/immich
IMMICH_BUILD_URL=``https://github.com/immich-app/immich/actions/runs/24350167851
IMMICH_BUILD_IMAGE=v2.7.5
DEVICE=openvino
IMMICH_REPOSITORY_URL=``https://github.com/immich-app/immich
IMMICH_BUILD_IMAGE_URL=``https://github.com/immich-app/immich/pkgs/container/immich-machine-learning
I have no name!@4c757f631964:/usr/src$

I have Ollama working well with the SYCL container.

What tokens/s are you seeing with Ollama and SYCL? Have you tried a vulkan backend?