UDFs are not necessarily required for applying models from ML libraries at scale, but they can provide some benefits in terms of performance and ease of use.
When using other libraries such as TensorFlow, PyTorch, SpaCy, Keras, etc., they are not optimized for distributed processing by default. In this case, using UDFs or the mapInPandas() method can provide a way to scale the models efficiently, by parallelizing the processing across the Spark cluster.
Anyways, it ultimately depends on the specific requirements of your project.