Zaimplementowałem dość szeroką gamę nieliniowych solverów na GPU, w tym LBFGS, Barzilai Borwein zejście gradientowe i nieliniowy gradient sprzężony.
W tym celu najbardziej nieskuteczny jest nieliniowy gradient sprzężony Dai i Yuan . Zasadniczo inna wersja nieliniowego gradientu sprzężonego może być bardziej wydajna (na przykład CG-DESCENT), ale może być również trudniejsza do wdrożenia.
LBFGS jest ogólnie bardzo dobrym wyborem i chyba, że naprawdę nie masz ochoty na pamięć, to prawdopodobnie najlepsze miejsce na rozpoczęcie.
Zarówno gradient sprzężony, jak i BFGS wymagają przeszukiwania linii, w których fp32 staje się problemem. Zamiast używać standardowych warunków Wolfe'a do wyszukiwania linii, sugerowałbym użycie przybliżonego warunku Wolfe'a sugerowanego tutaj . Artykuł jest trochę zaangażowany, ale ważne jest równanie 4.1. Zasadniczo wyraźnie wprowadzają precyzję, z jaką można obliczyć swoją funkcję.
Uwagi dotyczące GPU:
Masz wiele małych problemów, które nieco różnią się od mojego przypadku użycia jednego dużego problemu. Zastanów się nad uruchomieniem 1 problemu na blok GPU (a raczej wypaczenia), jeśli możesz zrównoleglić oceny funkcji i gradientu, aby użyć wszystkich wątków w bloku. W ten sposób nie stanowi problemu, jeśli różne problemy wymagają innej liczby iteracji.
Jeśli nie jest to opcja, wybrałbym solver LBFGS. Jeśli twoja funkcja jest dobrze zachowana, możesz po prostu użyć kroku o wielkości 1 (unikając przeszukiwania linii) i po prostu uruchomić wszystkie problemy dla określonej liczby iteracji.