@@ -186,8 +186,24 @@ def env_int(
186186# in validate_prebuilt_choice. Disabled for now: the llama-server GPU forward pass
187187# JIT-compiles CUDA kernels on first load and stalls every install and update by
188188# minutes on Blackwell (sm_100). The check and the source-build fallback it triggers
189- # are kept intact -- set this to True to re-enable them.
189+ # are kept intact -- set this to True, or set UNSLOTH_LLAMA_STAGED_VALIDATION=1, to
190+ # re-enable them (#5854 gap 2).
190191_RUN_STAGED_PREBUILT_VALIDATION = False
192+
193+
194+ def staged_validation_enabled () -> bool :
195+ """True when the expensive llama-server GPU smoke test should run.
196+
197+ Default off (Blackwell CUDA JIT stalls installs). Opt in via the module
198+ constant or ``UNSLOTH_LLAMA_STAGED_VALIDATION`` (1/true/yes/on). Used by both
199+ the prebuilt path and setup.sh's source-build post-check (#5854).
200+ """
201+ if _RUN_STAGED_PREBUILT_VALIDATION :
202+ return True
203+ raw = os .environ .get ("UNSLOTH_LLAMA_STAGED_VALIDATION" , "" ).strip ().lower ()
204+ return raw in ("1" , "true" , "yes" , "on" )
205+
206+
191207INSTALL_LOCK_TIMEOUT_SECONDS = 300
192208INSTALL_STAGING_ROOT_NAME = ".staging"
193209GITHUB_AUTH_HOSTS = {"api.github.com" , "github.com" }
@@ -5868,9 +5884,10 @@ def validate_prebuilt_choice(
58685884 # so they are always validated. For an approved bundle the sha256 manifest
58695885 # already proves integrity, so its runtime smoke test -- a cold CUDA-JIT pass
58705886 # costing minutes on Blackwell sm_100 -- is gated behind
5871- # _RUN_STAGED_PREBUILT_VALIDATION, disabled for now. The check and the
5872- # source-build fallback it triggers are kept intact; flip the flag to restore it.
5873- if choice .expected_sha256 is None or _RUN_STAGED_PREBUILT_VALIDATION :
5887+ # staged_validation_enabled() (constant or UNSLOTH_LLAMA_STAGED_VALIDATION),
5888+ # disabled for now. The check and the source-build fallback it triggers are
5889+ # kept intact; flip the flag / env to restore it (#5854).
5890+ if choice .expected_sha256 is None or staged_validation_enabled ():
58745891 validate_quantize (
58755892 quantize_path ,
58765893 probe_path ,
@@ -5891,6 +5908,49 @@ def validate_prebuilt_choice(
58915908 return server_path , quantize_path
58925909
58935910
5911+ def validate_existing_install (
5912+ install_dir : Path ,
5913+ * ,
5914+ install_kind : str | None = None ,
5915+ host : HostInfo | None = None ,
5916+ ) -> None :
5917+ """Run the staged smoke test against an already-built llama.cpp tree (#5854).
5918+
5919+ Used by setup.sh after a GPU source build when ``UNSLOTH_LLAMA_STAGED_VALIDATION``
5920+ is set. Raises ``PrebuiltFallback`` on failure so the caller can retry CPU.
5921+ """
5922+ host = host or detect_host ()
5923+ bin_dir = install_dir / "build" / "bin"
5924+ server_name = "llama-server.exe" if host .is_windows else "llama-server"
5925+ quantize_name = "llama-quantize.exe" if host .is_windows else "llama-quantize"
5926+ server_path = bin_dir / server_name
5927+ quantize_path = bin_dir / quantize_name
5928+ if not server_path .is_file ():
5929+ raise PrebuiltFallback (f"llama-server not found at { server_path } " )
5930+
5931+ with tempfile .TemporaryDirectory (prefix = "unsloth-llama-source-validate-" ) as tmp :
5932+ work_dir = Path (tmp )
5933+ probe_path = work_dir / "stories260K.gguf"
5934+ quantized_path = work_dir / "stories260K-q4.gguf"
5935+ download_validation_model (probe_path , validation_model_cache_path (install_dir ))
5936+ if quantize_path .is_file ():
5937+ validate_quantize (
5938+ quantize_path ,
5939+ probe_path ,
5940+ quantized_path ,
5941+ install_dir ,
5942+ host ,
5943+ )
5944+ validate_server (
5945+ server_path ,
5946+ probe_path ,
5947+ host ,
5948+ install_dir ,
5949+ install_kind = install_kind ,
5950+ )
5951+ log (f"staged source-build validation succeeded for { install_dir } " )
5952+
5953+
58945954def validate_prebuilt_attempts (
58955955 attempts : Iterable [AssetChoice ],
58965956 host : HostInfo ,
@@ -6345,6 +6405,24 @@ def parse_args() -> argparse.Namespace:
63456405 "fork). Use --output-format json."
63466406 ),
63476407 )
6408+ resolve_group .add_argument (
6409+ "--validate-install" ,
6410+ metavar = "DIR" ,
6411+ help = (
6412+ "Run the staged llama-server smoke test against an existing build "
6413+ "tree (setup.sh source-build post-check, #5854). Exit 2 on failure. "
6414+ "Normally gated by UNSLOTH_LLAMA_STAGED_VALIDATION; this flag always "
6415+ "runs the check."
6416+ ),
6417+ )
6418+ parser .add_argument (
6419+ "--install-kind" ,
6420+ default = None ,
6421+ help = (
6422+ "Install kind for --validate-install GPU offload (e.g. linux-cuda, "
6423+ "linux-rocm, macos-arm64). When omitted, host detection decides."
6424+ ),
6425+ )
63486426 parser .add_argument (
63496427 "--output-format" ,
63506428 choices = ("plain" , "json" ),
@@ -6381,6 +6459,17 @@ def emit_resolver_output(payload: dict[str, Any], *, output_format: str) -> None
63816459
63826460def main () -> int :
63836461 args = parse_args ()
6462+ if args .validate_install is not None :
6463+ try :
6464+ validate_existing_install (
6465+ Path (args .validate_install ),
6466+ install_kind = args .install_kind ,
6467+ )
6468+ except PrebuiltFallback as exc :
6469+ print (str (exc ), file = sys .stderr )
6470+ raise SystemExit (EXIT_FALLBACK ) from exc
6471+ return EXIT_SUCCESS
6472+
63846473 if args .resolve_llama_tag is not None :
63856474 resolved = resolve_requested_llama_tag (
63866475 args .resolve_llama_tag ,
0 commit comments