๐Ÿ“ Checkpoint-2026-09-01-llama-cpp-listatt-collabcore.md

Checkpoint (2026-09-01) โ€” llama.cpp Vision Captioning Built & Deployed, ListAttBBC Media Player, CollabCore Consolidation

Status: Everything below is DONE and CONFIRMED WORKING on both Clone and Live, except where flagged otherwise. This was a very long overnight session (evening of 08-31 through late morning 09-01) โ€” this checkpoint exists specifically so a fresh session doesn't need to re-derive any of it.


1. PyTorch + open_clip migration to Live โ€” COMPLETE, VALIDATED

Follows directly from the 08-31 checkpoint's "rebuild in progress" state.

2. ffmpeg โ€” CONFIRMED WORKING ON LIVE (was previously untested post-migration)

3. ISE search-query logging โ€” COMPLETE, DEPLOYED

Motivated by discovering query_log_reader.py had a broken regex (expected bare smf-queries[PID]:, actual format is smf-queries <caller>:[PID]:) that made it report 0 queries despite a full log.

4. llama.cpp โ€” BUILT, WORKING, MIGRATED TO LIVE, CAPTIONING VALIDATED

Why llama.cpp instead of BLIP/HuggingFace

Originally explored getting Rust working on Clone (for BLIP image captioning + Andrew's own interest in having more languages available). Confirmed real wall: rustup's prebuilt rustc needs glibc 2.17+; building Rust from source is a genuinely hard bootstrap problem (rustc needs an existing Rust compiler to build itself). Decision: pivot away from HuggingFace-transformers/Rust-tokenizers entirely. llama.cpp's multimodal support (libmtmd, GGUF format) does the same job โ€” pure C/C++, buildable with the same devtoolset-7 toolchain that already built PyTorch โ€” no Rust/glibc-2.17 dependency at all. This pattern (avoid touching the base OS/glibc, stay on tools buildable against the existing toolchain) held for a second, independent problem tonight, which is a strong signal it's the right general strategy for this box.

whisper.cpp was identified as the equivalent path for audio transcription but deprioritized in favor of finishing image captioning first (see ยง5 below for where transcription actually ended up).

The build saga (Clone) โ€” every real bug hit, in order

  1. PR_SET_PTRACER undeclared (ggml.c) โ€” CentOS 6's kernel headers predate this Linux 3.4 constant. Fixed with a #ifndef/#define 0x59616d61/#endif guard.
  2. <filesystem> not found (tools/ui/embed.cpp) โ€” GCC 7 only has <experimental/filesystem>, C++17's finalized <filesystem> came in GCC 8. This specific file (the web UI's asset-embedding tool) wasn't actually needed โ€” disabled the whole server/UI build instead: -DLLAMA_BUILD_SERVER=OFF -DLLAMA_BUILD_UI=OFF -DLLAMA_USE_PREBUILT_UI=OFF.
  3. _mm256_set_m128 undeclared (ggml-cpu/arch/x86/quants.c) โ€” initially worked around by disabling GGML_AVX2/GGML_BMI2/GGML_NATIVE, but this turned out not to be the real fix (see bug #8 below). The actual correct fix: the file already had a proven GCC-7 workaround pattern for the analogous integer intrinsic (MM256_SET_M128I macro using _mm256_insertf128_si256/_mm256_castsi128_si256) โ€” added the exact same pattern for the float variant (MM256_SET_M128 macro using _mm256_insertf128_ps/_mm256_castps128_ps256), replaced all 8 call sites. This intrinsic gap was a real GCC-7 header gap, unrelated to actual AVX2 hardware support.
  4. More <filesystem> gaps, same GCC-7-vs-8 issue, found repeatedly file-by-file until a full-repo sweep was done: ggml-backend-dl.h, ggml-backend-reg.cpp, common/download.cpp, common/hf-cache.cpp, plus ~20 more files across the repo (mostly unbuilt targets โ€” tests, server, tools not in use). Batch-fixed all 25 files matching ^#include <filesystem>$ at once via sed/xargs. Real gotcha hit here: Andrew's shell has alias grep='grep --color=always' โ€” this silently embedded ANSI escape codes into piped filenames, corrupting every sed/xargs target with a "No such file or directory" error that looked like a completely different bug. Fixed by using \grep (bypasses the alias) for any command whose output gets piped into something else. Standing lesson for future sessions on this box: always use \grep, not grep, when piping output.
  5. API-shape differences beyond simple renaming โ€” directory_entry::is_regular_file()/is_directory()/is_symlink() (member functions) don't exist in GCC 7's TS-based filesystem; replaced with the free-function forms (fs::is_regular_file(entry.status()), fs::is_symlink(entry.symlink_status()) โ€” note symlink_status() not status(), since the latter follows symlinks). path::lexically_normal() and path::lexically_relative() don't exist in the TS version at all โ€” hand-wrote portable reimplementations (lexically_normal_compat(), lexically_relative_compat()) using only primitives that do exist in the TS API (begin()/end()/root_name()/is_absolute()/has_root_directory()). fs::relative() as a free function is also missing โ€” reimplemented (relative_compat()) in terms of the above two.
  6. Link-order bug: -lstdc++fs (needed because GCC 7's experimental filesystem lives in a separate static library, unlike GCC 9+ where it's folded into libstdc++) was being placed by CMAKE_EXE_LINKER_FLAGS/CMAKE_SHARED_LINKER_FLAGS before libggml.so on the actual link command line โ€” GNU ld only resolves symbols from a library if it's positioned after what needs them. Fixed by switching to CMAKE_CXX_STANDARD_LIBRARIES="-lstdc++fs", which CMake places at the true end of the link line.
  7. llama-app unified-binary target failure: unrelated โ€” tries to link llama-server-impl/llama-cli-impl, which don't exist since the server was disabled in step 2. Not needed at all; sidestepped by building the specific target directly (cmake --build build --target llama-mtmd-cli) instead of the default all target.
  8. Stale libmtmd.so after multiple reconfigures: initial fix attempt (deleting just build/tools/mtmd/CMakeFiles/mtmd.dir and rebuilding) accidentally also deleted the CMake-generated build.make, causing a "No rule to make target" error โ€” fixed by re-running the configure step to regenerate build files.
  9. std::vector<ggml_tensor*>::vector() undefined reference โ€” this was the deepest bug. Confirmed via nm -D that the plain default constructor specifically was left as an unresolved external symbol in libmtmd.so, while other operations on the same type (_M_default_append etc.) were correctly weakly-defined in the same library. Ruled out: symbol visibility flags (none set anywhere in the project's CMake files), stale build state (reproduced identically in a genuinely fresh full clean rebuild โ€” mv build build_pre_clean_rebuild, fresh configure+build from zero). Real root cause, found via nm/ldd-style investigation and confirmed empirically: this CPU (Clone's physical Intel i7-3520M, Ivy Bridge, 2012) does not support FMA instructions (FMA came with Haswell, 2013) โ€” yet -mfma was in the actual compile flags (confirmed via reading flags.make directly), because GGML_NATIVE=OFF alone doesn't disable it; FMA has its own separate GGML_FMA CMake option. Fixed with -DGGML_FMA=OFF. This was not an AVX2 problem at all (that theory from bug #3 was a red herring for this specific crash) โ€” it was a completely separate, genuinely different hardware-instruction-set mismatch.
  10. Confirmed via /proc/cpuinfo on both boxes: Clone (physical i7-3520M) has sse, sse2, ssse3, sse4_1, sse4_2, avx, f16c โ€” no avx2, no fma. Live (DigitalOcean droplet) actually has MORE capability than Clone โ€” sse, sse2, ssse3, fma, sse4_1, sse4_2, avx, bmi1, avx2, bmi2 โ€” genuinely has AVX2 and FMA. So the AVX2/FMA-disabling flags used to make the build testable on Clone are strictly conservative for Live (Live's CPU is a superset of what Clone can run) โ€” safe to migrate as-is, just leaves some Live-side performance on the table that could theoretically be recovered with a Live-specific rebuild later, not urgent.
  11. llama-mtmd-cli --help initially produced Illegal instruction (SIGILL) โ€” this was the FMA bug (#9) manifesting at runtime, not a separate issue. Confirmed fixed: clean --help output, exit code 0, after the GGML_FMA=OFF fix.

Final working build config (Clone)

cmake -B build -DLLAMA_BUILD_SERVER=OFF -DLLAMA_BUILD_UI=OFF -DLLAMA_USE_PREBUILT_UI=OFF -DGGML_AVX2=OFF -DGGML_BMI2=OFF -DGGML_NATIVE=OFF -DGGML_FMA=OFF -DLLAMA_BUILD_TESTS=OFF -DCMAKE_CXX_STANDARD_LIBRARIES="-lstdc++fs"
cmake --build build --config Release -j 4 --target llama-mtmd-cli

Plus the source patches: PR_SET_PTRACER define in ggml.c; MM256_SET_M128 macro + 8 call sites in quants.c; <experimental/filesystem> + namespace swap across 25 files; lexically_normal_compat/lexically_relative_compat/relative_compat helpers + call-site fixes in common/download.cpp and common/hf-cache.cpp; template class std::vector<ggml_tensor*>; explicit instantiation added to tools/mtmd/clip.cpp (this was tried as a workaround for the FMA bug before the real cause was found โ€” turned out unnecessary once GGML_FMA=OFF was applied, but harmless to leave in place).

Migration to Live โ€” COMPLETE, VALIDATED

Model โ€” SmolVLM-500M, real captions confirmed on BOTH Clone and Live

Qwen3-ASR (transcription) โ€” downloaded, NOT yet tested

Started down the path of testing llama-mtmd-cli's native --audio support (confirmed present in --help output, and whisper-enc.cpp was seen compiling as part of libmtmd during the build) as a way to do transcription without needing a separate whisper.cpp project. Deliberately chose Qwen3-ASR-0.6B over Ultravox (a documented, real problem: Ultravox is alignment-tuned and has been reported to refuse/hallucinate on "triggering" content โ€” a real practical risk given this forum's actual subject matter; ASR-specific models don't have this problem since their only job is transcription, not conversational judgment). Downloaded both Qwen3-ASR-0.6B-Q8_0.gguf and its mmproj to Live (and Clone, in parallel โ€” model files are pure data, no compatibility risk, unlike the compiled binary). Not yet actually run against the extracted video_audio.wav โ€” this is the natural next step for a fresh session.

5. ListAttBBC.php โ€” v6.7.1, media playback for audio/video/image, CollabCore consolidation

The actual feature: audio/video/image playback

CollabCore consolidation โ€” real mess, fully resolved

6. Dev backup โ€” IN PROGRESS, discovered to be less useful than expected

Andrew started backing up Live's new state (PyTorch/CLIP, Python 3.8.18, ffmpeg, llama.cpp, ListAttBBC, ISE, LMV) to Dev. Real limitation surfaced: Dev is 32-bit, while all of tonight's compiled binaries (PyTorch's .so extensions, llama-mtmd-cli, ffmpeg, likely the custom Python 3.8.18 build) are 64-bit โ€” architecturally incompatible, not a config issue. A backup to Dev would preserve source/script files and GGUF model data usefully, but would NOT provide "restore and immediately run" disaster recovery for any of tonight's actual compiled work โ€” that would need a full rebuild from source again (faster now that the fixes are known, but not instant). Whether Dev's 32-bit-ness is a long-standing mismatch with Clone/Live (both confirmed 64-bit) is an open question, flagged as worth its own look in a future session, not resolved tonight.

Standing constraints/rules carried forward

Immediate next steps for a fresh session

  1. Test Qwen3-ASR-0.6B against /root/video_audio.wav on Live (llama-mtmd-cli -m .../Qwen3-ASR-0.6B-Q8_0.gguf --mmproj ... --audio /root/video_audio.wav -p "Transcribe this audio.").
  2. Patch MiscSearch.py's one real ISE_text_viewer.html path reference to point at Sources/CollabCore/ instead of The_ISE_Project/.
  3. Update Andrew's cc shell alias to point at the renamed /var/www/html/Collabware (not /var/www/html/CollabCore).
  4. Confirm removal of the vestigial qf_search_bridge.php .htaccess exception didn't break anything.
  5. Wire real CLIP embeddings + SmolVLM captions into MediaIndexer.py/MediaSearch.py's SimilarityRule (the original ISEmedia goal this whole saga was ultimately in service of) โ€” replacing the mock media_store.json data that's been standing in for it.
  6. Decide whether/how to reconcile Dev's 32-bit architecture with Clone/Live's 64-bit, if Dev is meant to stay a real mirror environment going forward.