LLM training parameters explanation

Quick overview of LLM MLX LORA training parameters.

weight_decayA regularization technique that adds a small penalty to the weights during training to prevent them from growing too large, helping to reduce overfitting. Often implemented as L2 regularization.examples: 0.00001 – 0.01
grad_clipShort for gradient clipping — a method that limits (clips) the size of gradients during backpropagation to prevent exploding gradients and stabilize training.examples: 0.1 – 1.0
rankRefers to the dimensionality or the number of independent directions in a matrix or tensor. In low-rank models, it controls how much the model compresses or approximates the original data.examples: 4, 8, 16 or 32
scaleA multiplier or factor used to adjust the magnitude of values — for example, scaling activations, gradients, or learning rates to maintain numerical stability or normalize features.examples: 0.5 – 2.0
dropoutA regularization method that randomly “drops out” (sets to zero) a fraction of neurons during training, forcing the network to learn more robust and generalizable patterns.examples: 0.1 – 0.5

YOLOx ONNX models use in Frigate

YOLOX is an anchor-free version of YOLO, with a simpler design but better performance! It aims to bridge the gap between research and industrial communities. For more details, please refer to our report on Arxiv.

https://yolox.readthedocs.io/en/latest/demo/onnx_readme.html

https://github.com/Megvii-BaseDetection/YOLOX/tree/main/demo/ONNXRuntime

To configure this in Frigate:

detectors:
  onnx:
    type: onnx
model:
  model_type: yolox
  width: 640
  height: 640
  input_tensor: nchw
  input_dtype: float_denorm
  path: /config/yolox_m.onnx
  labelmap_path: /labelmap/coco-80.txt

Google Coral TPU and TensorRT (Frigate + NVIDIA GPU/TensorRT)

These are two majors which allow to run object detection models. Google Coral TPU is a physical module which can be in a form of USB stick. TensorRT is a feature of GPU runtime. Both allows to run detection models on them.

Coral TPU:

And TensorRT:

Compute Capabilities requirements

CC 5.0 is required to run DeepStack and TensorRT, but 7.0 to run Ollama moondream:1.8b. Even having GPU with CC 5.0 which is minimum required to run for instance TensorRT might be not enough due to some minor differences in implementation. It is better to run on GPU with higher CC. Moreover running on CC 5.0 means that GPU is older one which leads to performance degradation even as low as having 2 or 3 camera feeds for analysis.

Running TensorRT detection models (popular ones) requires little VRAM memory, 300 – 500 MB but it requires plenty of GPU cores and supplemental physical components to be present in such GPU, with high working clocks. In other words, you can fit those models in older GPUs but it will not perform well.

Other side of the story is to run Ollama which is GenAI requiring CC 7.0 and higher. Ollama with moondream:1.8b which is the smallest available detection model still requires little more than 3GB of VRAM.

TensorRT on Geforce MX940

You can run TensorRT object detector from Frigate on NVIDIA Geforce 940MX with CC 5.0, but it will get hot at the same time you launch it. It run on driver 550 with CUDA 12.4 as follows on only one camera RTSP feed:

So this is not an option as we may burn this laptop GPU quickly. Configuration for TensorRT:

detectors:
  tensorrt:
    type: tensorrt
    device: 0

model:
  path: /config/model_cache/tensorrt/yolov7-320.trt
  input_tensor: nchw
  input_pixel_format: rgb
  width: 320
  height: 320

To start Docker container you need to pass YOLO_MODELS environment variable:

docker run -d \
  --name frigate \
  --restart=unless-stopped \
  --stop-timeout 30 \
  --mount type=tmpfs,target=/tmp/cache,tmpfs-size=1000000000 \
  --shm-size=1024m \
  --device /dev/bus/usb:/dev/bus/usb \
  --device /dev/dri/renderD128 \
  -v ./frigate-media:/media/frigate \
  -v ./frigate-config:/config \
  -v /etc/localtime:/etc/localtime:ro \
  -e FRIGATE_RTSP_PASSWORD='password' \
  -e YOLO_MODELS=yolov7x-640 \
  -p 8971:8971 \
  -p 8554:8554 \
  -p 8555:8555/tcp \
  -p 8555:8555/udp \
  --gpus all \
  ghcr.io/blakeblackshear/frigate:stable-tensorrt

Pleas notice that Docker image is different if you want to run use GPU with TensorRT than without it. It is also not possible to run hardware accelerated decoder using FFMPEG with 940MX so disable it by passing empty array:

cameras:
  myname:
    enabled: true
    ffmpeg:
      inputs:
        - path: rtsp://user:pass@addr:port/main
          roles:
            - detect
            - record
      hwaccel_args: []

However if you would like to try hardware decoder with different GPU or CPU the play with this values:

preset-vaapi
present-nvidia

TensorRT on “modern” GPU

It is the best to run TensorRT on modern GPU with highest possible CC feature set. It will run detection fast, it will not get hot as quickly. Moreover it will have hardware support for video decoding. And even more you could run GenAI on the same machine.

So the minimum for object detection with GenAI descriptions is to have 4 GB VRAM. In my case it is NVIDIA RTX 3050 Ti Mobile which runs 25% at most with 4 – 5 camera feeds.

Google Coral TPU USB module

To run Coral detector:

detectors:
  coral:
    type: edgetpu
    device: usb

But first you need to install and configure it:

sudo apt install python3-pip python3-dev python3-venv libusb-1.0-0
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt update
sudo apt install libedgetpu1-std

You can also run TPU in high power mode:

sudo apt install libedgetpu1-max

And finally configure USB:

echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1a6e", GROUP="plugdev", MODE="0666"' | sudo tee /etc/udev/rules.d/99-edgetpu-accelerator.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

Remember to run Coral via USB 3.0 as running it via USB 2.0 will cause performance drop by a factor of 2 or even 3 times. Second thing, to run Coral, first plug it in. Wait until it is recognized by the system:

lsusb

At first you will see not Google, but 1a6e Global Unichip. After TPU is initialized you will see 1da1 Google Inc:

You can pass Coral TPU via Proxmox USB device, but after each Proxmox restart you need to take care of TPU initialization:

Demaskowanie “możliwości” ChatGPT

Wstęp

Dzisiaj wyjątkowo będzie po polsku na temat ChatGPT. Zadałem sobie nieco trudu i wypróbowałem jego “możliwości” z zakresu programowania jako, że zasłyszałem o takiej opcji. Moim ulubionym w ostatnim czasie tematem jest OpenCL, zatem….

JA: to napisz mi kernel OpenCL który służy do sortowanie liczb zmiennoprzecinkowych

Dostałem sortowanie bąbelkowe…. i to jeszcze na floatach. W sumie to nie poprosiłem o double, więc nie mogę narzekać. Ale serio, sortowanie bąbelkowe, na GPU w OpenCL?

__kernel void sort(__global float *data, int length) {
    int i = get_global_id(0);
    int j = get_global_id(1);

    if (i < length && j < length) {
        if (data[i] > data[j]) {
            float temp = data[i];
            data[i] = data[j];
            data[j] = temp;
        }
    }
}

Konwersacja

Spróbowałem porozmawiać na ten temat z chatem tak aby dowiedzieć się dlaczego tak zaproponował oraz czy po kilku wskazówkach nie mógłby zrewidować swoich odpowiedzi na bardziej przystające do zadanego pytania:

JA: no ale przecież sortowanie w przestrzeni globalnej nie uda się ponieważ na GPU będą jednocześnie uruchomione pozostałe instancje tego kernela, co doprowadzi do nieprawidłowych wyników, twoja odpowedź jest nieprawidłowa, nie bieżesz pod uwagę kontekstu tego uruchomienia.
Chat: Przepraszam, to prawda. Sortowanie w przestrzeni globalnej jest nieprawidłowe, ponieważ wiele instancji tego jądra mogą być jednocześnie uruchamiane na GPU i może to prowadzić do nieprawidłowych wyników. W celu uniknięcia tego problemu należy użyć innego algorytmu sortowania, który umożliwia sortowanie w jednej instancji, lub rozbić sortowanie na wiele mniejszych sekwencji i sortować je oddzielnie.
JA: jaki zatem sugerujesz algorytm do sortowanie danych używając kernel OpenCL
Chat: Istnieje wiele algorytmów sortowania, które można użyć w kernelach OpenCL. Najbardziej popularne…

No i zamiast dostać propozycję pod OpenCL, dostałem ogólną odpowiedź z podręcznika o algorytmach nieprzystosowanych do programowania współbieżnego.

JA: moim zdaniem to błędna odpowiedź ponieważ będzie to sortowanie bitoniczne i pozycyjne oraz ewentualnie sortowanie z przesunięciem
Chat: Sortowanie bitoniczne i pozycyjne to popularne algorytmy sortowania używane w OpenCL. Sortowanie z przesunięciem jest mniej popularne, ale może być używane w niektórych sytuacjach. Wszystko zależy od wymagań i wymagań danego zastosowania.
JA: to napisz mi proszę przykład kernela OpenCL dla sortowania z przesunięciem.

No i dostałem co prawda, coś co przypomina shift-sort ale z globalną barierą.

__kernel void shiftSort(__global float *inputArray, int arrayLength) {
    int globalId = get_global_id(0);
    int stride = 1;

    while (stride < arrayLength) {
        int index = globalId * stride * 2;

        if (index + stride < arrayLength) {
            if (inputArray[index] > inputArray[index + stride]) {
                float temp = inputArray[index];
                inputArray[index] = inputArray[index + stride];
                inputArray[index + stride] = temp;
            }
        }

        stride *= 2;
        barrier(CLK_GLOBAL_MEM_FENCE);
    }
}
JA: dlaczego założyłeś barierę na pamięć globalną?
Chat: Bariera na pamięć globalną jest zastosowana w powyższym kernel OpenCL, aby zapewnić synchronizację między wszystkimi wątkami. W trakcie sortowania z przesunięciem każdy wątek sortuje swoją część danych wejściowych i jednocześnie jest uzależniony od wyniku sortowania wątków z innych części danych. Bariera na pamięć globalną gwarantuje, że wszystkie wątki zakończą sortowanie swoich danych i będą gotowe do następnego kroku sortowania, zanim sortowanie zostanie kontynuowane. To zapewnia poprawność wyniku sortowania i unika problemów związanych z nieprawidłowym dostępem do pamięci.
JA: a czy przypadkiem bariera globalna nie dotyczy wyłącznie pojedynczej grupy roboczej z N wątków?
Chat: Tak, bariera globalna działa na pojedynczej grupie roboczej i synchronizuje wątki w tej grupie, ale nie wpływa na inne grupy robocze w tym samym kernelu. W OpenCL, bariery na pamięć globalną służą do synchronizacji wątków w grupie roboczej i zapobiegają race conditions, gdy wiele wątków dostępuje i modyfikuje te same dane.

Wnioski

No i tutaj skończyła się przygoda z tym programem, bowiem próby doprecyzowania czegokolwiek powodowały albo błąd albo te same odpowiedzi. Podsumowując fakty mamy tutaj bardzo sprawne narzędzie, które zostało nakarmione mnóstwem informacji, nawet ciężko mi sobie wyobrazić jakie to są ilości. Wiedza tego mechanizmu kończy się na 2021 roku i nie ma podłączenia bieżącego do internetu. Zapytane czy używa CUDA do swojej pracy odpowiedziało twierdząco.

Tak szybkie działanie modelu wymaga ogromych ilości pamięci operacyjnej i bardzo dużej ilości rdzeni obliczeniowych aby procesować wejście i generować odpowiedzi. Brzmi to jak gigantyczna infrastruktura oparta o system rozproszony i tysiące kart GPU przetwarzające całość tego wsadu. Pytanie kiedy zacznie był płatne, czy jak zacznie dobrze odpowiadać czy jak ludzie się od tego uzależnią?