Commit graph

4,672 commits

Author SHA1 Message Date
Roland Tannous
08d9c84f1f Merge pull request #359 from unslothai/fix/stream-manual-slice-dataset
fix: stream HF dataset when manual slice is specified
2026-03-11 01:13:51 +04:00
Manan17
9523e5c1f9 fixing embedding model search 2026-03-10 21:12:24 +00:00
Shine1i
2895518f0c fix(setup): stop nuking llama.cpp in setup 2026-03-10 22:03:01 +01:00
Wasim Yousef Said
29e56e8649 Merge pull request #361 from unslothai/fix/tooltip-z-index
Increase tooltip z-index to appear above dropdowns
2026-03-10 22:01:30 +01:00
imagineer99
d572c43814 fix: increase tooltip z-index to appear above dropdowns 2026-03-10 20:57:12 +00:00
Manan17
3b0b002b34 fixing logging for each step 2026-03-10 20:32:40 +00:00
Roland Tannous
21ef22a9ff fix: skip streaming when dataset_slice_start > dataset_slice_end
Prevents training on the wrong row range when start exceeds end by
falling back to full download where existing clamping handles it.
2026-03-10 20:21:34 +00:00
imagineer99
5dcbf86d09 fix: reject negative manual dataset slices
Prevent negative Train Split Start/End values in the dataset advanced UI and sanitize payload mapping so negative slice values are never sent to the backend.

Made-with: Cursor
2026-03-10 20:13:46 +00:00
Roland Tannous
226f251589 fix: guard against negative dataset_slice_end before streaming
Fall back to full download when dataset_slice_end is negative,
avoiding an empty stream.take(0) that would produce a broken dataset.
2026-03-10 20:12:42 +00:00
Roland Tannous
b91cdda2b9 Merge pull request #354 from unslothai/fix/audio-train-completions
fix: uncheck train_on_completions for audio models
2026-03-11 00:05:51 +04:00
Roland Tannous
949f2ac87e Merge pull request #358 from unslothai/fix/sharded-gguf
fix: download all GGUF shards for split models
2026-03-11 00:05:01 +04:00
Roland Tannous
970a029108 fix: stream HF dataset when manual slice is specified
Instead of downloading the full dataset and then slicing, use
streaming mode to only fetch the rows needed (up to slice_end + 1)
when a manual dataset slice is configured.
2026-03-10 19:50:53 +00:00
Roland Tannous
c986174c56 fix: preserve zero-valued dataset slice boundaries in embedding worker
Use explicit None checks instead of falsy `or` for slice_start and
slice_end so that a valid slice_end=0 is not replaced with the full
dataset length.
2026-03-10 19:33:10 +00:00
Roland Tannous
b84202e8db fix: restrict shard siblings to exact basename and total count
startswith(prefix) could match unrelated split variants whose names
extend the selected file's prefix (e.g. model-Q8_0-v2-00001-of-...).
Now builds an exact regex from the chosen file's base prefix and shard
total so only true siblings are downloaded.
2026-03-10 19:28:26 +00:00
Shine1i
18a60b930a chore/fix(studio): add placeholder dropdowns for dataset subset and splits in disabled state 2026-03-10 20:27:11 +01:00
Roland Tannous
b8678a3ed6 fix: pass hf_token for gated embedding models and key cache by token
- Forward hf_token to FastSentenceTransformer.from_pretrained() so
  private/gated embedding repos authenticate correctly
- Key _embedding_detection_cache by (model_name, hf_token) tuple so
  unauthenticated lookups don't shadow subsequent authenticated ones
2026-03-10 19:20:12 +00:00
Roland Tannous
d635846b8d fix: use exact variant matching and shard-prefix discovery for split GGUFs
Substring matching (e.g. "Q8_0" in filename) could match superset
variants like "IQ8_0", causing wrong quantizations to be downloaded.
Now uses word-boundary regex for variant matching and discovers split
shards by shared filename prefix rather than treating all variant
matches as shards.
2026-03-10 19:13:03 +00:00
Roland Tannous
d6ae910edc fix: propagate is_embedding into worker subprocess config
start_training() cherry-picks kwargs into a config dict but was missing
is_embedding, so config.get("is_embedding", False) in worker.py always
returned False and embedding training never ran.
2026-03-10 19:05:47 +00:00
Roland Tannous
defa761fb2 fix: download all GGUF shards for split models (e.g. 7B Q8_0)
LlamaCppBackend.load_model() only downloaded the first matching GGUF
file. For split models (e.g. 7B Q8_0 with 3 shards), llama-server
needs all shards present. Now collects and downloads all matching files.
2026-03-10 19:04:10 +00:00
Roland Tannous
846cc2cf2a fix: always force-uncheck trainOnCompletions for pure audio models in dataset check
Separate pure-audio from audio-VLM logic in runDatasetCheck so pure
audio models are always forced to trainOnCompletions=false regardless
of dataset type, while audio VLMs (gemma3n) only uncheck when the
dataset is audio.
2026-03-10 19:02:49 +00:00
Roland Tannous
d9f2d08267 fix: reset isAudioModel on model config fetch failure
Clear stale isAudioModel in the fallback path when getModelConfig
fails, preventing a previously-selected audio model's flag from
leaking into the next model selection.
2026-03-10 19:00:56 +00:00
Roland Tannous
5a086353ab feat: add embedding model training support
Add end-to-end embedding/sentence-transformer training pipeline using
FastSentenceTransformer, SentenceTransformerTrainer, and
MultipleNegativesRankingLoss with BatchSamplers.NO_DUPLICATES.

Backend:
- Add is_embedding_model() detection via HF tags + pipeline_tag
- Add /check-embedding/ API route and EmbeddingCheckResponse
- Extend derive_model_type() to return "embeddings"
- Add _run_embedding_training() in worker.py with progress callbacks,
  stop handling, LoRA (task_type=FEATURE_EXTRACTION), and model saving
- Add is_embedding field to TrainingStartRequest and ModelDetails
- Add YAML configs for 5 models: all-MiniLM-L6-v2, bge-m3,
  embeddinggemma-300m, gte-modernbert-base, Qwen3-Embedding-0.6B

Frontend:
- Wire isEmbeddingModel flag through store, API types, and mappers
- Force packing=false, train_on_completions=false, warmup_ratio=0.03
- Hide packing and train_on_completions checkboxes for embedding models
- Auto-set modelType to "embeddings" from backend model_type response
2026-03-10 18:10:09 +00:00
Roland Tannous
5b8f5bc554 fix: improve advisor prompts for more reliable column role assignment
- Pass 1: clearer definition of "conversational" vs non-conversational,
  constrained dataset_type to specific enum values
- Pass 2: much more explicit worked examples with step-by-step reasoning,
  added "skip" role for metadata columns, stronger reminder at end that
  all-user is wrong
- Pass 3: returns raw text instead of JSON for cleaner system prompts,
  removed system message to give model more freedom
2026-03-10 18:01:20 +00:00
Roland Tannous
1430bbc604 fix: uncheck train_on_completions for audio models
Pure audio models (orpheus, sparktts, whisper, sesame-csm) now
always have trainOnCompletions auto-unchecked when selected.
Gemma3n (audio_vlm) only unchecks when the dataset is audio.

- Add is_audio to frontend ModelConfigResponse (backend already returns it)
- Add isAudioModel state to training config store
- Auto-set trainOnCompletions=false for pure audio models on model load
- Auto-set trainOnCompletions=false for audio VLMs when dataset is audio
- Respect manual user override via existing _trainOnCompletionsManuallySet flag
2026-03-10 17:39:35 +00:00
imagineer99
c895cc56a4 fix: redesign summary step with consistent card layout, icons, and compact spacing 2026-03-10 17:38:10 +00:00
Roland Tannous
cb389fb756 Merge pull request #353 from unslothai/feat/dataset-shortlist-and-model-type
Curated dataset shortlists and model type plumbing
2026-03-10 21:31:16 +04:00
Roland Tannous
2fc50ff0cf refactor: advisor maps columns to roles instead of generating templates
The advisor now only assigns columns to user/assistant roles and
generates a system prompt. Templates (user_template, assistant_template)
are removed entirely — the LLM was frequently putting all columns in
user or copying actual data values into templates.

Column values are now used directly as message content, grouped and
concatenated by role. This is simpler, more robust, and prevents the
class of bugs where the advisor generates bad template content.
2026-03-10 17:17:27 +00:00
Roland Tannous
21cff233e5 feat: add model_type field to backend /config and /list responses
Derive a single model_type string ("text" | "vision" | "audio" | "embeddings")
from existing is_vision and audio_type detection, so the frontend doesn't have
to infer modality from scattered boolean flags.
2026-03-10 16:54:19 +00:00
Roland Tannous
a30153e1bb fix: improve Pass 2 prompt to correctly split INPUT/OUTPUT columns
The LLM was putting all columns in user_template (e.g. summarization
dataset had both document AND summary as user input). Fixed by:

- Reframed system message: explicitly states user=INPUT, assistant=OUTPUT
- Added 4 concrete correct examples (summarization, NLI, translation, QA)
  showing exactly how to split columns
- Added "NEVER put the output/target column in the user template" rule
- Added sanity check: if assistant_template has no column placeholders,
  reject the result and fall back to simple classification
2026-03-10 16:47:50 +00:00
Roland Tannous
5db251b31c fix: include label mapping in Pass 3 system prompt generation
Pass 3 now sees the label mapping from Pass 2 (e.g. "0 = does not follow,
1 = follows, 2 = entailed") so the generated system prompt can explain
what each label value means. Also bumped to 2-4 sentences to give room
for the label descriptions.
2026-03-10 16:21:54 +00:00
Roland Tannous
49a4089dfa feat: Beta badge, generated System column, fix table scroll
- Add "Beta" badge next to AI Assist button text
- When advisor generates a system prompt, show it as a "System (generated)"
  column prepended to the data table so user can see it alongside data
- Fix table being squished to near-zero height when advisor notification
  banner is present: add min-h-[250px] to table wrapper, change body
  from overflow-hidden to overflow-auto
2026-03-10 16:14:16 +00:00
Roland Tannous
78489e41c4 refactor: 3-pass advisor — dedicated system prompt generation
Pass 1: Classify dataset type (unchanged)
Pass 2: Generate user/assistant templates + label mapping + column roles
  (system_prompt removed from this pass to keep it focused)
Pass 3: Generate system prompt (only for non-conversational datasets)
  - Dedicated pass with focused prompt that sees the templates from Pass 2
  - Skipped entirely for conversational datasets
  - Produces specific, task-relevant system prompts
2026-03-10 16:07:30 +00:00
Roland Tannous
76cc5b19cb fix: show generated templates in UI, make system prompt optional
- System prompt is now optional — LLM only generates one when the task
  is ambiguous from the data alone (persona, domain, format constraints)
- Sanitize system_prompt extraction (handle literal "null" string)
- Show system prompt, user template, and assistant template in the
  advisor notification banner so user can see exactly what was generated
- Templates displayed in monospace with labeled sections
2026-03-10 16:01:57 +00:00
Roland Tannous
48a5e49313 fix: remove Pass 3 self-scoring, trust Pass 2 output directly
The LLM was bad at scoring its own conversion quality — rejecting good
Pass 2 output (score 5/10 for a perfectly usable conversion). Instead:
- Remove Pass 3 entirely (saves ~0.4s and one inference call)
- Trust Pass 2 output and return it to the user
- Build notification from Pass 1 classification info instead
- User can always adjust mapping via dropdowns if they disagree
2026-03-10 15:56:48 +00:00
Roland Tannous
ed849b7d0d fix: advisor quality gate, better prompts, always show AI Assist button
- Reject advisor result when Pass 3 scores < 6 or is_acceptable=false,
  falls back to simple column classification instead of using bad output
- Improved Pass 2 prompt: explicit rules for label_mapping completeness,
  {column_name} vs {column_name_name} for mapped labels, column_roles
  must match which template uses them
- Build suggested_mapping from ALL template-referenced columns (not just
  first match per role) — fixes hypothesis being dropped from SNLI mapping
- Guard against LLM returning literal string "null" for revised_system_prompt
- Always show AI Assist button when available, even when mapping looks complete
2026-03-10 15:51:14 +00:00
Roland Tannous
ab58121cd8 fix: harden template mapping for complex column types and curly braces
- Handle dict columns (e.g. squad answers) by extracting text instead
  of raw repr()
- Handle list columns by joining or extracting single value
- Catch ValueError in .format() calls (stray { } in column data)
- Add missing json import to dataset_utils.py
2026-03-10 15:43:35 +00:00
Roland Tannous
202780c32c feat: Dataset Conversion Advisor — multi-pass LLM for non-conversational datasets
Non-conversational HF datasets (e.g. stanfordnlp/snli) were naively mapped
column→role, producing poor training results. The AI Assist button now runs
a 3-pass advisor using Qwen 7B that:
1. Fetches the HF dataset card/README to understand the dataset purpose
2. Classifies the dataset type and determines if conversion is needed
3. Generates a system prompt, user/assistant templates with {column}
   placeholders, and label mappings (e.g. 0→entailment)
4. Validates the conversion quality (score ≥7/10 required)

Architecture: advisor metadata flows as __-prefixed keys in
custom_format_mapping (e.g. __system_prompt, __user_template,
__assistant_template, __label_mapping). The existing _apply_user_mapping()
detects these keys and routes to template-based conversation construction.
No __ keys = existing simple mode (backwards compatible).

Backend: upgraded llm_assist.py (7B default, multi-pass advisor,
HF card fetching), extended API models, added _apply_template_mapping()
to dataset_utils.py.

Frontend: extended store with advisor state fields, wired AI Assist
to store templates/system prompt, inject __ metadata in training request,
show advisor notification banner in mapping card.
2026-03-10 15:39:56 +00:00
Roland Tannous
c2dd0f4cf1 fix: download all GGUF shards for split models (e.g. 7B Q8_0)
LlamaCppBackend.load_model() and precache_helper_gguf() only downloaded
the first matching GGUF file. For split models (e.g. 7B Q8_0 with 3
shards), llama-server needs all shards present. Now collects and
downloads all matching files.
2026-03-10 15:08:20 +00:00
Roland Tannous
7f1fd28acd debug: decode first sample after train_on_completions masking 2026-03-10 14:08:14 +00:00
imagineer99
3de197ac31 rename: tts model type to audio for broader category support 2026-03-10 13:28:49 +00:00
Roland Tannous
49b29fb1fd debug: fix dataset access - result is a dict, use dataset['dataset'] 2026-03-10 13:19:31 +00:00
imagineer99
968f11f60a feat: infer tts model type from backend is_audio flag 2026-03-10 12:57:40 +00:00
Roland Tannous
21cd9f9d02 debug: improve sample preview with type info and traceback 2026-03-10 12:56:24 +00:00
Roland Tannous
a36c073770 debug: switch to print() for subprocess visibility 2026-03-10 12:49:01 +00:00
Roland Tannous
97612af993 debug: add temporary log statements for dataset preview and VLM instruction 2026-03-10 12:35:55 +00:00
imagineer99
8cba556bea feat: curated dataset shortlists and model type plumbing 2026-03-10 12:00:09 +00:00
Roland Tannous
5d471d7e4a feat: add AI Assist button for user-triggered column classification
Move LLM-assisted column mapping from silent /check-format automation
to an explicit "AI Assist" button in the dataset mapping dialog. This
makes the feature transparent and user-controlled.

- Remove llm_classify_columns() from check_dataset_format() (heuristic-only)
- Remove auto-save suggested_mapping from use-training-actions.ts
- Add POST /api/datasets/ai-assist-mapping endpoint (receives preview
  samples from frontend, no dataset re-loading needed)
- Add AiAssistMappingRequest/Response models
- Add aiAssistMapping() frontend API function
- Add Sparkles AI Assist button to DatasetMappingCard with loading state
- Wire up handleAiAssist handler in dataset-preview-dialog.tsx
2026-03-10 11:09:01 +00:00
Roland Tannous
6ae931ca46 Merge pull request #343 from unslothai/fix/cli-changes
Fix/cli changes
2026-03-10 14:38:35 +04:00
Roland Tannous
a26a5cc6be Merge pull request #352 from unslothai/fix/cancel-training
Fix/cancel training
2026-03-10 14:38:30 +04:00
Roland Tannous
0ec340d3e1 fix: LLM-assisted mapping flows from /check-format to training
- Frontend auto-saves suggested_mapping into datasetManualMapping when
  check-format returns requires_manual_mapping=false, so the mapping
  flows to training via custom_format_mapping (no redundant AI calls)
- Backend returns meaningful warning when column detection fails
  (LLM-generated or static fallback) for both text and VLM datasets
- /check-format endpoint merges check_dataset_format warnings with
  existing URL-based image detection warnings
2026-03-10 09:58:58 +00:00