Skip to content

[Studio] Show non exported models in chat UI#4892

Open
Datta0 wants to merge 3 commits intounslothai:mainfrom
Datta0:issue-4888-chat-adapter
Open

[Studio] Show non exported models in chat UI#4892
Datta0 wants to merge 3 commits intounslothai:mainfrom
Datta0:issue-4888-chat-adapter

Conversation

@Datta0
Copy link
Copy Markdown
Collaborator

@Datta0 Datta0 commented Apr 7, 2026

Fixes #4888
We now fetch LoRAs and trained models (for full finetune) to be shown without one needing to explicitly "export". The models are already on disk so we just show them

Note: We do not yet show intermediate checkpoints from the training run. Only the final stored file.

image
{"timestamp": "2026-04-07T07:35:08.349908Z", "level": "info", "event": "request_completed", "method": "GET", "path": "/api/models/cached-models", "status_code": 200, "process_time_ms": 19.01}
{"timestamp": "2026-04-07T07:35:09.858555Z", "level": "info", "event": "Found 3 trained models in /home/datta0/.unsloth/studio/outputs"}
{"timestamp": "2026-04-07T07:35:09.858716Z", "level": "info", "event": "Detected base model from config.json (model_name): unsloth/Qwen3-4B"}
{"timestamp": "2026-04-07T07:35:09.858815Z", "level": "info", "event": "Detected base model from adapter_config.json: unsloth/SmolLM-135M-Instruct-bnb-4bit"}
{"timestamp": "2026-04-07T07:35:09.858882Z", "level": "info", "event": "Detected base model from adapter_config.json: unsloth/Qwen3-8B"}
{"timestamp": "2026-04-07T07:35:09.858953Z", "level": "info", "event": "Found 0 exported models in /home/datta0/.unsloth/studio/exports"}
{"timestamp": "2026-04-07T07:35:09.859388Z", "level": "info", "event": "request_completed", "method": "GET", "path": "/api/models/local", "status_code": 200, "process_time_ms": 3.62}
{"timestamp": "2026-04-07T07:35:09.859649Z", "level": "info", "event": "request_completed", "method": "GET", "path": "/api/models/loras", "status_code": 200, "process_time_ms": 3.82}
{"timestamp": "2026-04-07T07:35:26.155667Z", "level": "info", "event": "Loading text model: /home/datta0/.unsloth/studio/outputs/unsloth_Qwen3-4B_1775545843"}
{"timestamp": "2026-04-07T07:35:26.155982Z", "level": "info", "event": "GPU Memory [Before loading /home/datta0/.unsloth/studio/outputs/unsloth_Qwen3-4B_1775545843] CUDA (NVIDIA B200): 0.01GB/178.35GB (0.0% used, 178.35GB free)"}

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request expands the Studio Chat's model discovery to include full finetune outputs in addition to LoRA adapters. It introduces a more robust base model detection mechanism via get_base_model_from_checkpoint and updates the backend scanning logic and frontend UI to support and label these "Full" finetune models. A potential issue was identified in the directory-name-based base model detection where an unexpected naming pattern could result in an invalid model string.

Comment on lines +1588 to +1591
model_parts = parts[1:-1]
base_model = "unsloth/" + "_".join(model_parts)
logger.info("Detected base model from directory name: %s", base_model)
return base_model
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the directory name doesn't follow the expected unsloth_{model}_{timestamp} pattern (e.g., just unsloth_12345), model_parts will be empty, resulting in an invalid base_model string like unsloth/. Adding a check to ensure model_parts is not empty before returning would be safer.

Suggested change
model_parts = parts[1:-1]
base_model = "unsloth/" + "_".join(model_parts)
logger.info("Detected base model from directory name: %s", base_model)
return base_model
model_parts = parts[1:-1]
if model_parts:
base_model = "unsloth/" + "_".join(model_parts)
logger.info("Detected base model from directory name: %s", base_model)
return base_model

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: be146de451

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +796 to +797
trained_models = scan_trained_models(outputs_dir = resolved_outputs_dir)
for display_name, model_path, model_type in trained_models:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Filter non-LoRA training outputs from LoRA scan response

This loop now appends every scan_trained_models entry (including model_type == "merged") into /api/models/loras. The chat UI determines LoRA compare mode by checking whether the active checkpoint exists in state.loras (useIsLoraCompare in chat-page.tsx), so full-finetune checkpoints from training are now misclassified as LoRAs and routed through adapter-toggle compare logic. In that scenario users get an incorrect base-vs-finetuned flow on non-PEFT models; only true adapter outputs should be returned in the LoRA list (or merged checkpoints should be surfaced via a separate list/flag consumed by compare-mode selection).

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to chat with finetuned model.

1 participant