Skip to content

WIP: Training Pipeline - #376

Closed
lukehinds wants to merge 6 commits into
mainfrom
transform
Closed

WIP: Training Pipeline#376
lukehinds wants to merge 6 commits into
mainfrom
transform

Conversation

@lukehinds

Copy link
Copy Markdown
Collaborator

No description provided.

@lukehinds lukehinds changed the title Training Pipeline WIP: Training Pipeline Oct 18, 2025
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @lukehinds, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands DeepFabric's capabilities by introducing a complete training pipeline that integrates seamlessly with HuggingFace Transformers. Users can now leverage local LLMs for generating synthetic datasets and then fine-tune these models using advanced techniques like LoRA and quantization, all within a unified framework. This enhancement provides greater control and flexibility for users who prefer local model operations and end-to-end model development.

Highlights

  • New Training Pipeline: Introduced a comprehensive DeepFabricPipeline for end-to-end workflows, covering synthetic data generation, model training, and deployment.
  • HuggingFace Transformers Integration: Added TransformersProvider to enable the use of local HuggingFace models for both inference (topic tree and dataset generation) and structured output via Outlines.
  • Supervised Fine-Tuning (SFT) Module: A new deepfabric.training module was added, featuring DeepFabricSFTTrainer, SFTTrainingConfig, LoRAConfig, and QuantizationConfig to facilitate efficient fine-tuning of Large Language Models.
  • Transformers Rate Limit Configuration: Implemented a specific rate limit configuration for local Transformers models, tailored to handle hardware-related issues like CUDA Out-of-Memory errors rather than traditional API rate limits.
  • Enhanced Documentation and Examples: New documentation (docs/transformers-integration.md) and Jupyter notebooks (notebooks/cuda_dataset_and_training.ipynb, notebooks/quickstart.ipynb) were added to guide users through the new Transformers integration and training capabilities.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

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

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.

Code Review

This pull request introduces a significant new feature: a complete training pipeline with support for local HuggingFace Transformers models. The changes include a new DeepFabricPipeline for high-level workflows, configuration models for SFT, LoRA, and quantization, and a DeepFabricSFTTrainer that integrates with TRL. The implementation is robust, with good error handling, dependency validation, and resource management for local models. The PR also adds comprehensive documentation, examples, and notebooks to guide users.

My review focuses on improving maintainability and performance in the new modules. I've suggested refactoring a conditional block to use a dictionary lookup for clarity, moving repeated imports out of a frequently called function to improve performance, and extracting a hardcoded multi-line string into a constant. Overall, this is a well-executed and substantial addition to the library.

Comment thread deepfabric/llm/client.py
Comment on lines +169 to +188
def transformers_callable(prompt: str, schema: type[BaseModel], **gen_kwargs):
# Import generator module to create logits processor
from outlines import generator # noqa: PLC0415

# Create JSON schema string from Pydantic model
json_schema_str = schema.model_json_schema()
# Get JSON string representation
import json # noqa: PLC0415

json_schema_json = json.dumps(json_schema_str)

# Convert to logits processor for transformers
logits_processor = generator.get_json_schema_logits_processor(
None, # backend_name (None for auto-detect)
outlines_model,
json_schema_json,
)
# Generate using the model's generate method
return outlines_model.generate(prompt, output_type=logits_processor, **gen_kwargs)

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

For performance, these imports (outlines.generator and json) should be moved outside the transformers_callable function. Since this function will be called for every generation, the imports will be executed repeatedly, adding unnecessary overhead. They can be moved to the top of the if provider == 'transformers': block, for instance after line 161.

Comment thread deepfabric/llm/transformers_provider.py Outdated
Comment on lines +189 to +197
if self.config.torch_dtype:
if self.config.torch_dtype == "auto":
model_kwargs["torch_dtype"] = "auto"
elif self.config.torch_dtype == "float16":
model_kwargs["torch_dtype"] = torch.float16
elif self.config.torch_dtype == "bfloat16":
model_kwargs["torch_dtype"] = torch.bfloat16
elif self.config.torch_dtype == "float32":
model_kwargs["torch_dtype"] = torch.float32

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

This if/elif chain can be simplified by using a dictionary to map the string torch_dtype values to their corresponding torch objects. This would make the code more readable and easier to extend if more dtypes are supported in the future.

Suggested change
if self.config.torch_dtype:
if self.config.torch_dtype == "auto":
model_kwargs["torch_dtype"] = "auto"
elif self.config.torch_dtype == "float16":
model_kwargs["torch_dtype"] = torch.float16
elif self.config.torch_dtype == "bfloat16":
model_kwargs["torch_dtype"] = torch.bfloat16
elif self.config.torch_dtype == "float32":
model_kwargs["torch_dtype"] = torch.float32
if self.config.torch_dtype:
dtype_map = {
"auto": "auto",
"float16": torch.float16,
"bfloat16": torch.bfloat16,
"float32": torch.float32,
}
if self.config.torch_dtype in dtype_map:
model_kwargs["torch_dtype"] = dtype_map[self.config.torch_dtype]

Comment on lines +246 to +251
self.tokenizer.chat_template = (
"{% for message in messages %}"
"{{ '<|im_start|>' + message['role'] + '\n' + message['content'] + '<|im_end|>\n' }}"
"{% endfor %}"
"{% if add_generation_prompt %}{{ '<|im_start|>assistant\n' }}{% endif %}"
)

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

This hardcoded ChatML template string could be defined as a module-level constant for better readability and to avoid having a multi-line string in the middle of a method. For example: DEFAULT_CHATML_TEMPLATE = "..."

@lukehinds lukehinds closed this Oct 25, 2025
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.

1 participant