„Permission denied” na /dev/kfd — rozwiązanie z grupami AMD
Działa z sudo, na moim koncie nie
Autor Jakub Rusinowski
Błąd
Unable to open /dev/kfd read-write: Permission denied rocminfo: HSA_STATUS_ERROR_OUT_OF_RESOURCES hsa api call failure at: ... HSA_STATUS_ERROR_OUT_OF_RESOURCES
| Jeśli widzisz | Przyczyną jest | Przejdź do |
|---|---|---|
sudo rocminfo działa, a samo rocminfo nie | Twój użytkownik nie należy do grup render i video | Rozwiązanie 1: dodaj grupy — ta asymetria to cała diagnoza |
Uruchomiłeś usermod, a groups dalej ich nie pokazuje | Przynależność do grup ustala się przy logowaniu | Rozwiązanie 2: wyloguj się i zaloguj ponownie |
| Tobie działa, ale usługa Ollama nadal nie może użyć GPU | Usługa działa na koncie ollama, które też potrzebuje tych grup | Rozwiązanie 3: dodaj konto usługi |
| Permission denied wyłącznie w kontenerze | Identyfikatory grup z hosta nie zostały przekazane do kontenera | Rozwiązanie 4: --group-add z numerycznymi identyfikatorami |
| Na tej dystrybucji żadna z grup nie istnieje | Różne dystrybucje inaczej nazywają te węzły i inaczej przypisują im właścicieli | Rozwiązanie 5: trwałą odpowiedzią jest reguła udev |
Kiedy się pojawia
Tropem jest asymetria i sama w sobie stawia diagnozę: uruchom dokładnie to samo polecenie z sudo, a zadziała; uruchom je jako ty — zawiedzie. Nic w ROCm, w twojej karcie ani w sterowniku nie jest zepsute. Po prostu nie możesz otworzyć pliku urządzenia.
- Właśnie zainstalowałeś ROCm i
rocminfozawodzi przy pierwszym uruchomieniu na twoim koncie. - Ktoś podpowiedział, żeby uruchamiać wnioskowanie przez sudo, zadziałało — i tak już zostało.
- Ollama działa jako usługa systemd i zgłasza brak GPU, choć rocminfo w twojej powłoce działa.
- Kontener z ROCm zawodzi na /dev/kfd, podczas gdy na hoście wszystko gra.
- Dodałeś się do grupy, nie zobaczyłeś zmiany i uznałeś, że polecenie nie zadziałało.
Co się właściwie dzieje
ROCm sięga do GPU przez dwa węzły urządzeń: /dev/kfd, węzeł obliczeniowy udostępniany przez kernel fusion driver, oraz /dev/dri/render*, węzły renderujące. Oba należą do grup systemowych — umownie render i video — właśnie po to, by dowolny lokalny użytkownik nie mógł zlecać zadań karcie. Twoje konto domyślnie nie należy do żadnej z nich, więc każde wywołanie ROCm zawodzi już na open(). sudo omija tę kontrolę i dlatego obejście sprawia wrażenie działającego — i dlatego tyle osób kończy, uruchamiając wnioskowanie jako root, nie zdając sobie sprawy, że niczego nie naprawiły. Błąd wychodzi na wierzch myląco: HSA_STATUS_ERROR_OUT_OF_RESOURCES brzmi jak problem z pamięcią, a bardzo często jest tym właśnie problemem z uprawnieniami, widzianym warstwę wyżej.
Jak to naprawić
- 1
Dodaj swojego użytkownika do grup render i video
Jedno polecenie — i jest to udokumentowany warunek wstępny we własnym przewodniku instalacji ROCm od AMD.
-ama znaczenie: bez niegousermod -Gzastępuje całą twoją listę grup zamiast do niej dopisywać, co potrafi usunąć cię zsudoi odciąć od administrowania maszyną.Uwaga: Zawsze dodawaj -a.sudo usermod -G video,render $LOGNAMEbez tego zastępuje każdą twoją grupę dodatkową, łącznie z sudo — a na maszynie bez drugiego administratora to już problem do rozwiązania z nośnika ratunkowego.# bash sudo usermod -a -G video,render $LOGNAME # Confirm the account record was updated (this does NOT mean it is active yet) id -nG $LOGNAME ls -l /dev/kfd /dev/dri/render*Czy zadziałało?id -nGwypisuje render i video. Zwróć uwagę, że czyta to bazę kont — twoja bieżąca sesja wciąż ich nie ma, i o tym jest rozwiązanie 2.id -nG $LOGNAME | tr ' ' '\n' | grep -E '^(render|video)$' - 2
Wyloguj się i zaloguj ponownie — to ten krok, przez który ludzie sądzą, że się nie udało
Przynależność do grup ustala się w chwili tworzenia sesji. Twoja powłoka i każdy proces, jaki kiedykolwiek uruchomi, wciąż niosą listę grup sprzed wykonania
usermod, a ponawianie polecenia niczego nie zmieni. Wyloguj się z sesji graficznej w całości albo połącz na nowo przez SSH i spróbuj jeszcze raz.newgrp renderprzyznaje grupę wyłącznie w bieżącej powłoce — to przydatny szybki test, nie rozwiązanie, a świeży terminal jej nie dostanie.# bash — quick test without logging out (this shell only) newgrp render rocminfo | grep -i "Marketing Name:" # The real check, after logging out and back in groups rocminfo | grep -i "Marketing Name:"Czy zadziałało?groups— a nieid -nG— wypisuje render i video w zupełnie nowym terminalu, arocminfonazywa twoją kartę bez sudo.groups rocminfo | grep -c gfx - 3
Dodaj także konto usługi ollama, nie tylko swoje
To ta połowa, którą się pomija. Gdy Ollama działa jako usługa systemd, działa na koncie
ollama, a to konto potrzebuje takiej samej przynależności do grup. Naprawienie własnego logowania nic jej nie daje — i dokładnie dlategorocminfodziała w twoim terminalu, podczas gdy usługa upiera się, że GPU nie ma. Usługa przyjmuje nowe grupy przy restarcie, bez potrzeby logowania.# bash sudo usermod -a -G render,video ollama sudo systemctl restart ollama # What groups does the service user actually have? id -nG ollama journalctl -u ollama --no-pager -n 40 | grep -i -E "gpu|rocm|vulkan"Czy zadziałało?Log usługi zgłasza GPU, a załadowany model pokazuje umieszczenie na GPU, a nie na CPU.ollama run gemma3:1b "hi" && ollama ps - 4
Przekaż do kontenerów numeryczne identyfikatory grup
Wewnątrz kontenera nazwy grup nic nie znaczą — obraz ma własny
/etc/group, a jego gruparender, jeśli w ogóle istnieje, będzie miała inny numer. Jądro sprawdza numeryczny GID, więc to jego trzeba przekazać. Odczytaj numery zls -lnd, gdzie-nwypisuje liczby zamiast nazw, i podaj je do--group-add.# bash — -n gives numeric owners, which is what you need here ls -lnd /dev/kfd /dev/dri /dev/dri/* docker run --rm --device /dev/kfd --device /dev/dri \ --group-add 44 --group-add 993 \ rocm/dev-ubuntu-22.04 rocminfoCzy zadziałało?rocminfow kontenerze wypisuje agenta GPU. Sam agent CPU oznacza, że identyfikatory nadal są złe.docker run --rm --device /dev/kfd --device /dev/dri --group-add 44 --group-add 993 rocm/dev-ubuntu-22.04 rocminfo | grep -i "Marketing Name" - 5
Napisz regułę udev tam, gdzie dystrybucja robi to inaczej
Nie każda dystrybucja używa dla tych węzłów tych samych nazw i tego samego właściciela, a na części grupę potrafi zresetować aktualizacja pakietu sterownika. Reguła udev przypina własność po twojemu i przeżywa aktualizacje, co czyni ją trwałą odpowiedzią na maszynie, którą utrzymujesz. Najpierw sprawdź, jak te węzły faktycznie wyglądają — reguła ma pasować do twojego systemu, a nie do skopiowanego przykładu.
Uwaga: Reguła udev z trybem 0666 udostępnia węzeł obliczeniowy GPU każdemu lokalnemu użytkownikowi. Zamiast tego ustaw grupę i tryb 0660, chyba że masz konkretny powód, by zrobić inaczej.# bash — inspect first ls -l /dev/kfd /dev/dri/render* # Then pin ownership sudo tee /etc/udev/rules.d/70-amdgpu-compute.rules >/dev/null <<'EOF' KERNEL=="kfd", GROUP="render", MODE="0660" SUBSYSTEM=="drm", KERNEL=="renderD*", GROUP="render", MODE="0660" EOF sudo udevadm control --reload-rules && sudo udevadm triggerCzy zadziałało?Oba węzły urządzeń pokazują grupęrenderi trybcrw-rw----, a wartości te utrzymują się po restarcie.ls -l /dev/kfd /dev/dri/render* - 6
Przestań uruchamiać wnioskowanie jako rootNajczęstsze rozwiązanie
Warto powiedzieć to wprost, bo
sudo ollama servedziała i przez to kusi. Uruchamianie wnioskowania jako root oznacza, że każdy pobrany model, każdy plik zapisany przez proces i każdy błąd w szybko zmieniającym się stosie wykonują się z pełnymi uprawnieniami systemowymi — a do tego tworzy w katalogu modeli pliki należące do roota, których twoje zwykłe konto potem nie ogarnie. To nie jest rozwiązanie; to diagnoza przerobiona na nawyk. Zmiana grup powyżej zajmuje jedno polecenie i jedno wylogowanie.# bash — undo root-owned artefacts from earlier sudo runs sudo chown -R $LOGNAME:$LOGNAME ~/.ollama ls -ld ~/.ollama ~/.ollama/modelsCzy zadziałało?Twój katalog modeli należy do ciebie, a wnioskowanie działa bez sudo.ls -ld ~/.ollama/models && rocminfo | grep -c gfxSprawdź, co pasuje do Twojego sprzętusprawdź, co uciągnie twój Radeon, gdy ROCm już do niego dosięgnieOtwórz kalkulator VRAM →
Jeśli nic z tego nie pomogło
Jeśli uprawnienia są już poprawne, a ROCm nadal nie znajduje agenta GPU, problemem jest wsparcie, a nie dostęp — kolejnym przystankiem jest strona o nadpisaniu gfx i Vulkanie. Jeśli dzieje się to wyłącznie w kontenerach, strona o kontenerach omawia przekazywanie urządzeń i SELinuksa.
- ROCm nie obsługuje twojej karty AMD — HSA_OVERRIDE i Vulkan
- Twój kontener Dockera nie widzi GPU
- GPU AMD niewykrywane / ROCm nieobsługiwany — zacznij tutaj
- Wynik
groups,id -nG ollamaorazls -l /dev/kfd /dev/dri/render* - Czy
sudo rocminfodziała tam, gdzie samorocminfozawodzi - Twoja dystrybucja i wersja ROCm (
amd-smi version) - Przy kontenerach:
ls -lnd /dev/kfd /dev/dri /dev/dri/*i pełna linia docker run
Powiązane
Najczęściej zadawane pytania
Dlaczego ROCm działa z sudo, a na moim koncie nie?
Bo /dev/kfd i /dev/dri/render* należą do grup render i video, a root omija tę kontrolę. Twoje konto domyślnie nie należy do żadnej z nich, więc każde wywołanie ROCm zawodzi na open(). Ta asymetria sama w sobie stawia diagnozę.
Uruchomiłem usermod i nic się nie zmieniło. Nie zadziałało?
Zadziałało — tylko przynależność do grup ustala się przy logowaniu, więc twoja bieżąca sesja wciąż niesie starą listę. Wyloguj się i zaloguj ponownie albo połącz na nowo przez SSH. newgrp render przyznaje grupę w jednej powłoce do testów, ale nie przenosi się na nowe terminale.
Dlaczego usługa Ollama nadal nie widzi GPU?
Bo działa na koncie ollama, a nie na twoim, i to konto potrzebuje tych samych grup: sudo usermod -a -G render,video ollama, a potem restart usługi. Naprawienie własnego logowania nie ma na nią żadnego wpływu.
Co w tym kontekście znaczy HSA_STATUS_ERROR_OUT_OF_RESOURCES?
Mimo brzmienia to często ta sama awaria uprawnień widziana warstwę wyżej, a nie problem z pamięcią. Jeśli to samo polecenie działa spod sudo, traktuj rzecz jako uprawnienia i sprawdź przynależność do grup, zanim zaczniesz przyglądać się rozmiarom modeli.
Dlaczego kontenery potrzebują numerycznych identyfikatorów grup?
Bo nazwa grupy wewnątrz obrazu nie ma związku z nazwą na hoście, a jądro sprawdza numeryczny GID. Odczytaj numery przez ls -lnd /dev/kfd /dev/dri /dev/dri/* i przekaż każdy przez --group-add.