common: add json.h abstraction - #27511
Conversation
ServeurpersoCom
left a comment
There was a problem hiding this comment.
LGTM. Read it on a checkout: the only silent change is a braced pair in value position, array before and object now, and they are all converted to json::array() here, tests included. Nice side effect, operator[] const throws where master aborted on the assert.
Two nits, non blocking: tests/gguf-model-data.cpp still includes nlohmann/json.hpp directly, and the object iterator re-walks with std::next(begin(), idx) on every dereference.
Every copy now sits behind one translation unit, which is also where a depth bound would live. Is that the intent, so #27434 can be closed without waiting for nlohmann/json#5389?
There was a problem hiding this comment.
Nice work! I see 10% build time reduction on my M2 Ultra with 8 threads for the total project and about ~20% reduction for user-space code (common, tool, examples, tests).
Btw, I think there is a low-hanging fruit for reducing compilation time by amalgamating the models/*.cpp files as part of the build process.
| // json.cpp defines this specialization, it must be declared before any use of it | ||
| template <> common_json common_json::get<common_json>() const; | ||
|
|
There was a problem hiding this comment.
nit: I think this declaration can be safely removed
|
@ServeurpersoCom thanks for testing, I added your points as code comments
maintainers are actively working on the upstream PR, so that this point we can be sure that it will be fixed upstream. let's close the PR #27434 to avoid duplicated works
@ggerganov TIL that cmakelists has a feature called UNITY_BUILD, may worth giving it a try? |
|
rebased to make sure I'm not missing any code paths that were not migrated, will merge this PR once is CI is green |
|
@ngxson: is it just me or this merge broke my build on windows using clang? links issues (undefined symbols) |
|
Interesting; I haven't tested Windows in advance at all, but it's inevitable: when I rebase my working branch, the little dedicated Windows machine (exposed at https://www.serveurperso.com/ia/windows/ !) is going to run into trouble, I check this now! |
|
It's simply the build folder that needs to be deleted on my side. Windows OK |
|
@ServeurpersoCom - nope... still fails at my end even after using a clean build folder... BTW i do wonder now what was the potential fixed you proposed earlier? |
Are you building master itself, or a branch of your own on top of it? If you carry local changes under tools/server or common, that is where I would look first: every JSON type and call in that code has to move to the new common_json. The header include becomes common/json.h instead of nlohmann/json.hpp, any nlohmann::ordered_json in a signature or a using alias becomes common_json, and a braced array literal in value position no longer builds, so {a, b, c} has to be written as json::array({a, b, c}). |
indeed on a fork.... which i keep on rebased from master here. i'll keep you posted either way... i just started looking into it and thanks for the quick response ❤️ |
|
Found it — it was the For anyone hitting the same thing on Windows + clang + LTO: explicit template instantiations in a static/shared lib can come out as weak (W) symbols instead of exported (T), so the linker reports them as undefined even though they're in the object. @ServeurpersoCom: sorry if made you worry man 😅 looks like it a it's a clang-on-Windows LTO bug. |
|
I can confirm this regression on Windows when building with The root cause appears to be tied to the recent Autoparser refactoring, which introduced new JSON-template instantiations inside static libraries. Under Windows (COFF format), Instead of forcing users to abandon Clang or LTO, could we fix this at the CMake or source level?
I'd love to keep using |
|
could you try #27575 ? |
|
Confirmed! I tested PR #27575 and it resolves the LTO linking issue for me. Built successfully with Thanks for pointing me to the fix! |
@ngxson I haven't used this feature before, but it seems like what we need. |
* add common/json * migrate common * adapt jinja * migrate server * big wip * migrate tests * wip * revert some excessive changes * wip * wip 2 * revert redundant changes * fix server crash * various fixes * fix ci * harden a bit * clean up * rm json-shim * add some comments * rm redundant decl
Conflicts resolved: - common/CMakeLists.txt: keep both the fork's jsonl.cpp/.h and upstream's new json.cpp/.h (common_json wrapper, ggml-org#27511). - ggml/src/ggml-cuda/out-prod.cu: take upstream's removal of the redundant cublasSetStream (ggml-org#26574 binds the cuBLAS handle to its stream at creation). The fork's conditional lda for dequantized (quantized) src0 is unchanged; upstream's unconditional lda decl is dropped as it would redeclare it. - ggml/src/ggml-metal/ggml-metal.metal: upstream split the monolithic source into kernels/*.metal (ggml-org#26561). The fork's kernels were ported into the new layout: * quantize_q3_K / quantize_q4_K / quantize_mxfp4 -> kernels/quantize.h * kernel_cpy_* q3_K/q4_K/mxfp4 instantiations -> kernels/quantize.metal * adamw gclip, out_prod, out_prod_id, get_rows_back, repeat_back, cross_entropy_loss{,_back} -> kernels/misc.metal * rms_norm_back -> kernels/norm.metal * soft_max_back -> kernels/softmax.metal No CMake or enum changes are needed: kernel->library routing is built from each compiled library's functionNames. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Upstream restructured the code the memory work sits on. server: refactor sleep handling (ggml-org#27376) split slot reporting out of SERVER_TASK_TYPE_METRICS into a new SERVER_TASK_TYPE_SLOT_GET task, rewrote get_metrics around a cached snapshot served during sleep, and extracted the props body into get_res_props(). memory_data stays on server_task_result_metrics, the memory gauges keep their place on /metrics, and endpoint_memory is back in get_res_props(). /metrics during sleep must equal the last awake scrape. The model is unloaded by then, so update_cached_responses() now renders the memory series while the model is still loaded and use_cached_metrics() appends the cached string. The rendering moved into render_memory_metrics() and the breakdown into server_context_impl::get_memory_data(), so the awake and sleeping paths share one implementation. common: add json.h abstraction (ggml-org#27511) replaced nlohmann::json with common_json, which has no find(). The gauge loop uses contains() and at() instead.
…Sep-2026 llama.cpp Carries the non-gitlink hunks of utilityai#1121 ("Update llama.cpp 2026-09-02"): common/json.h gained a common_json_value abstraction on 2026-08-22 (ggml-org/llama.cpp#27511) that the old wrapper_common.cpp trips with a static_assert, plus the one-line model-params / mtmd field additions. Keeps this branch's 8c0b9cd pin (one day past utilityai#1121's b96806d; superset of the Metal fixes). Only matters for the `common` feature — ankerton/inference-stack builds with default-features = false and converts JSON-schema → GBNF in Rust. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* add common/json * migrate common * adapt jinja * migrate server * big wip * migrate tests * wip * revert some excessive changes * wip * wip 2 * revert redundant changes * fix server crash * various fixes * fix ci * harden a bit * clean up * rm json-shim * add some comments * rm redundant decl
* add common/json * migrate common * adapt jinja * migrate server * big wip * migrate tests * wip * revert some excessive changes * wip * wip 2 * revert redundant changes * fix server crash * various fixes * fix ci * harden a bit * clean up * rm json-shim * add some comments * rm redundant decl
* add common/json * migrate common * adapt jinja * migrate server * big wip * migrate tests * wip * revert some excessive changes * wip * wip 2 * revert redundant changes * fix server crash * various fixes * fix ci * harden a bit * clean up * rm json-shim * add some comments * rm redundant decl
* add common/json * migrate common * adapt jinja * migrate server * big wip * migrate tests * wip * revert some excessive changes * wip * wip 2 * revert redundant changes * fix server crash * various fixes * fix ci * harden a bit * clean up * rm json-shim * add some comments * rm redundant decl
Overview
Add a light-weight
common/json.hto avoid re-compilingjson.hppin multiple places. Also allow swapping another pimpl in the future if neededGoals:
nlohmann::jsonChanges to downstream code:
nlohmann::jsontocommon_jsonobj.push_back({key, val})is changed toobj[key] = valfor clarify;push_backcan be confused withstd::vectorin some placesstd::something<...> = obj["abc"], change to explicit= obj.get<std::something<...>>()to avoid excessive template instancesResults
End-to-end (compile common + server, exclude libllama/libmtmd, -j12):
Single-TU dev loop (touch tools/server/server-context.cpp, rebuild + link):
Binary size:
TODO:
remove the deps jinja --> common (the json-to-internal code path)maybe a follow-upRequirements