I'm Hai, an engineer in Ho Chi Minh City. Most of my work is getting vision models to run correctly and fast on the hardware they will actually ship on. At my day job I work on perception for UAVs: multi-camera fisheye calibration, depth for obstacle avoidance, and quantized models on Qualcomm NPUs. I'm also doing an M.Eng. in electronics at Ho Chi Minh City University of Technology.
The repos below are things I built to measure something properly. Each one has the raw numbers, the commands to reproduce them, and a section on what didn't work.
| Repo | What it measures |
|---|---|
| multistream-trt-pipeline | Several RTSP cameras into one GPU: hardware decode, batched TensorRT YOLO, a tracker per camera. Latency per stage and total FPS from 1 to 12 streams. |
| ros2-trt-detector | A ROS 2 node that runs a TensorRT detector on a camera topic. Holds 30 Hz at 640 and 1280 input, 14 to 19 ms from image stamp to detections. |
| yolo-tensorrt-edge (try in browser) | YOLO exported to ONNX and TensorRT at FP32, FP16 and INT8, with latency against COCO accuracy for each. |
| object-tracking-bench | ByteTrack and BoT-SORT on MOT17, scored with HOTA, MOTA and IDF1, PyTorch against TensorRT. |
| camera-calibration-report | Pinhole, fisheye and stereo calibration, judged on held-out images rather than the training error. |
| libero-vla-repro | Two robot policies (SmolVLA and pi0-FAST) re-run on the LIBERO benchmark, with confidence intervals and an honest look at why one fell short of its paper. |
| ppo-mujoco-control | PPO written from scratch for MuJoCo Hopper, HalfCheetah and Walker2d, against Stable-Baselines3 over 3 seeds, with an observation-normalisation ablation. |
| diffusion-policy-pusht (demo) | Diffusion Policy written from scratch against two BC baselines on state-based PushT: coverage 0.87 vs 0.64 and 0.54 over 3 seeds, with action chunks sampled live in the browser. |
| decision-transformer-offline (demo) | Decision Transformer against BC and %BC on offline MuJoCo: 45 runs over 3 seeds, where the simple baselines won, plus diagnostics that ruled out implementation bugs and learning-rate or training-length settings on the dataset tested. |
| vla-lora-finetune (rollouts) | A LoRA adapter fine-tuned on SmolVLA for one weak LIBERO task: no measurable gain on that task and a clear loss on another, with confidence intervals and side-by-side rollouts. |
| alphazero-connect4 (play in browser) | An AlphaZero-style Connect Four agent trained by self-play from random weights in 90 minutes, scored against minimax depth 1 to 6 at every checkpoint. |
| pcb-rp2040-usbc | A four-layer RP2040 board with USB-C, a 90 ohm USB pair and JLCPCB fab files, plus a 2x2 panel and a DFM check against the fab's published limits. |
| pcb-sample-preamp | A two-channel phantom-powered microphone preamp in KiCad, checked against the TI datasheet, with hand-routed inputs and fab files. |
| eagle-to-kicad-qwiic-button | An open-source Eagle board (SparkFun Qwiic Button, CC BY-SA) migrated to KiCad 10, with every net and copper segment checked against the original. |
| cad-sample-tests | A mechanical part drawing, a 1:50 floor plan, and a 1921 scanned drawing redrawn to its printed dimensions and overlaid on the original, delivered as DXF, DWG and PDF. |
| ttihp-snn-ascon | An Ascon-128 crypto core in Verilog, submitted to the Tiny Tapeout IHP 26a shuttle (130 nm). |
Outside of these: in 2026 I was the AI engineer on a city-scale drone pilot for traffic and urban-order monitoring in Hanoi (Lao Động, An ninh Thủ đô), and I co-authored MARS, a small multi-task Mamba model for mapless UAV navigation (IAAA 2026, Springer LNNS).
Day to day I use Python and C++, PyTorch, TensorRT, ONNX Runtime, OpenCV, CUDA, GStreamer, ROS 2 and KiCad.