Running abogen audio generation on ROCm
I recently discovered the abogen audio generation tool that is using Kokoro TTS model to generate audio from text. I was always using it using CPU without GPU acceleration, but I wanted to see if I could run it on my AMD GPU using ROCm. In this post, I will share my experience and the steps I took to get it running.
I have an integrated AMD GPU on my relativily new mini PC (that I bought before the memory shortage) and I wanted to see if I could leverage it for audio generation. My machine is fairly ordinary:
- AMD Ryzen 7 7735HS
- Integrated Radeon 680M
- Zorin OS 18.1
- Linux kernel 7.0
- No NVIDIA GPU
Abogen runs perfectly well on the CPU, but an 82M-parameter TTS model is exactly the sort of workload where even a modest GPU can make the application much more pleasant to use. But to make it work on my AMD GPU, I had to do a few things. First, I needed to install ROCm, which is AMD's open-source platform for GPU computing.
The less obvious problem was that the Radeon 680M has historically lived in an awkward part of the ROCm ecosystem. It is an RDNA2 integrated GPU with the gfx1035 target, and many older ROCm and PyTorch distributions either do not include kernels for it or require workarounds intended for nearby GPU architectures.
Fortunately, this situation has improved significantly.
First: identify the actual GPU target
Before installing anything, I checked what Linux was actually seeing:
lspci -nnk | grep -A3 -E 'VGA|3D|Display'
Which showed
Advanced Micro Devices, Inc. [AMD/ATI] Rembrandt [Radeon 680M]
Kernel driver in use: amdgpu
The CPU is:
AMD Ryzen 7 7735HS with Radeon Graphics
For ROCm, the important mapping is:
Radeon 680M -> Rembrandt -> gfx1035
That gfx1035 identifier here matters much more than just a marketing name. ROCm packages and compiled GPU kernels are ultimately selected using the GPU architecture target.
But why not just simply install rocm?
The traditional Linux ROCm setup typically involves installing AMD packages system-wide, often under /opt/rocm. But I deliberately avoided that.
The mini PC already had a working amdgpu kernel driver and Replacing a working graphics stack just to run one Python application seemed unnecessarily invasive.
And there is another reason for that. AMD's newer TheRock packaging now provides ROCm components and PyTorch builds as Python packages, including device-specific packages for gfx1035. That means ROCm can live inside the same virtual environment as Abogen instead of becoming another system-level SDK installation.
So Conceptually, the environment becomes:
abogen virtual environment
|
+-- ROCm runtime
+-- gfx1035 device libraries
+-- ROCm-enabled PyTorch
+-- Kokoro
+-- Abogen
Which would be a lot cleaner to install, remove and debug later.
Installing ROCm in a virtual environment
ROCm needs access to the kernel's GPU interfaces, particularly:
ls -l /dev/kfd
ls -l /dev/dri/render*
The user should normally have access through the render and video groups:
groups
So if needed, add your user to the render group:
sudo usermod -aG render,video "$USER"
Then log out and back in to apply the group changes. This is worth checking before touching Python. Otherwise, it is very easy to spend time debugging PyTorch when the actual problem is simply access to /dev/kfd.
Then I created a new Python virtual environment but take into consideration that abogen supports up to python 3.12, so I used that version:
python3.12 -m venv .venv
source .venv/bin/activate
Using uv venv would work equally well. But for this setup I cared more about controlling exactly which PyTorch build was installed than about whether the package installer was pip or uv.
Now the next step is to install PyTorch for the exact GPU target. The ROCm PyTorch builds are available on PyPI, and the torch package is built for specific GPU architectures. For my Radeon 680M, I needed the gfx1035 build. SO, Instead of installing the ordinary PyTorch package, I used AMD's ROCm repository and explicitly selected the 680M target:
pip install \
--index-url https://stable.repo.amd.com/rocm/whl-next/ \
"torch[device-gfx1035]" \
"torchvision[device-gfx1035]" \
torchaudio
The device-gfx1035 extra causes the environment to receive the GPU-specific code needed for the Radeon 680M.
The newer packaging also pulls in the matching ROCm runtime dependencies, so I do not need a separate /opt/rocm installation just to use PyTorch.
This is a significant improvement over older approaches where unsupported GPUs sometimes required tricks such as:
HSA_OVERRIDE_GFX_VERSION=...
I did not need that here.
The next step we needed to make sure that the ROCm runtime was working. I ran a simple test:
import torch
print(torch.__version__)
print(torch.version.hip)
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))
One slightly confusing detail is that ROCm PyTorch still uses the torch.cuda API.
So:
torch.cuda.is_available()
returning True does not mean CUDA or an NVIDIA GPU is being used.
PyTorch exposes CUDA and HIP devices through largely the same Python interface.
On a working ROCm installation, you expect something conceptually like:
HIP: ...
True
AMD Radeon 680M
I also tested an actual matrix multiplication:
device = "cuda"
a = torch.randn(1024, 1024, device=device)
b = torch.randn(1024, 1024, device=device)
c = a @ b
torch.cuda.synchronize()
print(c.device)
Device detection alone is not sufficient. Successfully executing kernels is the more meaningful test.
Installing abogen
Abogen already has an AMD installation option:
pip install abogen[rocm]
At the time I tested this, however, its ROCm extra was configured around the older PyTorch ROCm 6.4 nightly repository. Which is not the stack I wanted for gfx1035.
Instead, I have installed the correct ROCm-enabled PyTorch first and then installed ordinary Abogen:
pip install abogen
This allows Abogen to use the already-installed PyTorch package rather than selecting the ROCm stack on my behalf.
After installing Abogen, I repeated the PyTorch check to make sure dependency resolution had not silently replaced the ROCm build with a CPU-only version. That check is important whenever a higher-level Python application depends on PyTorch.
One thing I want to mention is that while researching the setup, I found Abogen issue #171. In that case, another AMD user successfully got GPU detection working but then encountered:
miopenStatusUnknownError
The failure happened during MIOpen's JIT compilation. The particular upstream bug discussed in that issue has since been fixed, but it highlighted something useful: testing torch.cuda.is_available() is not enough.
Abogen and Kokoro exercise convolutional neural-network operators, so I added a small MIOpen smoke test before trying a full audiobook:
import torch
import torch.nn as nn
model = nn.Sequential(
nn.Conv1d(64, 128, 3, padding=1),
nn.ReLU(),
nn.Dropout(0.2),
nn.Conv1d(128, 64, 3, padding=1),
).to("cuda")
x = torch.randn(1, 64, 512, device="cuda")
y = model(x)
torch.cuda.synchronize()
print(y.shape)
This exercises a much more representative path than a simple device query. If this fails, the problem is probably lower in the ROCm/PyTorch/MIOpen stack. If it works but Abogen fails, the debugging surface becomes much smaller.
The final step is to install and Abogen itself. With PyTorch and MIOpen working, the remaining installation is straightforward:
pip install abogen
Then to launch Abogen GUI, we run:
abogen
or for the web interface:
abogen-web
At that point, Abogen should detect the Radeon GPU through PyTorch. Its messages will still refer to a "CUDA GPU", because the application is ultimately checking PyTorch's torch.cuda interface. Under the hood, however, execution is happening through HIP and ROCm.
After getting the individual steps working, I wrapped them in an installation script.
I did not make the script a giant sequence of unconditional apt and pip commands. It performs checks between each stage:
- Confirm the OS is based on Ubuntu Noble (24.04).
- Confirm that the GPU is actually a Radeon 680M.
- Confirm that
amdgpuis the active kernel driver. - Check
/dev/kfdand DRM render devices. - Check
renderandvideogroup membership. - Create an Python 3.12 environment.
- Install ROCm/PyTorch specifically for
gfx1035. - Test PyTorch GPU detection.
- Run an actual GPU matrix multiplication.
- Run a MIOpen neural-network smoke test.
- Install Abogen.
- Verify that Abogen did not replace the ROCm-enabled PyTorch installation.
- Run the MIOpen test again.
The interesting part of this experiment was not really installing Abogen. It was that an integrated Radeon 680M, which used to require a fair amount of ROCm-specific experimentation, can now be treated as a real gfx1035 target using AMD's newer packaging. For this kind of application, I now prefer keeping the entire compute stack inside a Python environment:
Linux amdgpu driver
|
v
/dev/kfd
|
v
ROCm runtime in venv
|
v
PyTorch HIP
|
v
Kokoro
|
v
Abogen
Which will not bloat OS-level package management and will be easier to remove or upgrade later. And with my humble mini PC iGPU running a relatively small TTS model, that is exactly the level of ROCm integration I wanted. Now I could test whether this will improve the time it takes to generate audiobooks with Abogen. I might report on that in a future post with some concrete results.