diff --git a/docs/blog/posts/distilation-part1.md b/docs/blog/posts/distilation-part1.md index d2cf0d3..716003d 100644 --- a/docs/blog/posts/distilation-part1.md +++ b/docs/blog/posts/distilation-part1.md @@ -3,30 +3,24 @@ draft: False date: 2023-10-17 tags: - python - - distilation + - distillation - function calling - - tinetuning + - finetuning --- -# Introduction to `Instructions` from `Instructor`, finetuning from Python functions. +# Enhancing Python Functions with Instructor: A Guide to Fine-Tuning and Distillation -The core philosophy with the `instructor` library is to make language models backwards compatible with existing code. By adding Pydantic in the mix we're able to easily work with LLMs without much worry. +## Introduction -However, many times, a single function isn't just one LLM call. After the results are returned theres [validation](/docs/validation.md), some additional processing and formatting before you `return` the result. +Get ready to dive deep into the world of fine-tuning task specific language models with Python functions. We'll explore how the `instructor.instructions` streamlines this process, making the task you want to distil more efficient and powerful while preserving its original functionality and backwards compatibility. -But the promise of LLMs is that they can do all of this in one go. So how do we get there? Finetuning end to end is a great tool for enhancing language models. Instructor uses type hints via Pydantic to maintain backward compatibility. Distillation focuses on fine-tuning language models to imitate specific functions. +## Why You Need Instructor -## Challenges in Fine-tuning +Imagine you're developing a backend service that uses a mix old and new school ML practises, it may involve pipelines with multiple function calls, validations, and data processing. Sounds cumbersome, right? That's where `Instructor` comes in. It simplifies complex procedures, making them more efficient and easier to manage by adding a decorator to your function that will automatically generate a dataset for fine-tuning and help you swap out the function implementation. -Fine-tuning a model isn't as straightforward as just writing `def f(a, b): return a * b` to teach a model three-digit multiplication. Substantial data preparation is required, making logging for data collection cumbersome. Luckily OpenAI not only provides a fine-tuning script but also one for function calling which simplies the process backed by structured outputs! More over, the finetune allows us to avoid passing the schema to the model, resulting in less tokens being used! +## Quick Start: How to Use Instructor's Distillation Feature -## Role of Instructor in Easing the Process - -The feature `from instructor import Instructions` simplifies this. It decorates Python functions that return Pydantic objects, automatically creating a fine-tuning dataset when provided a handler for logging. This allows you to finetune a model to imitate a function's behavior. - -## How to Use Instructor's Distillation Feature - -Here's an example to illustrate its use: +Before we dig into the nitty-gritty, let's look at how easy it is to use Instructor's distillation feature to use function calling finetuning to export the data to a JSONL file. ```python import logging @@ -34,6 +28,7 @@ import random from pydantic import BaseModel from instructor import Instructions +# Logging setup logging.basicConfig(level=logging.INFO) instructions = Instructions( @@ -47,18 +42,38 @@ class Multiply(BaseModel): b: int result: int +# Define a function with distillation +# The decorator will automatically generate a dataset for fine-tuning +# They must return a pydantic model to leverage function calling @instructions.distil def fn(a: int, b: int) -> Multiply: resp = a * b return Multiply(a=a, b=b, result=resp) +# Generate some data for _ in range(10): a = random.randint(100, 999) b = random.randint(100, 999) print(fn(a, b)) ``` -## Logging output +## The Intricacies of Fine-tuning Language Models + +Fine-tuning isn't just about writing a function like `def f(a, b): return a * b`. It requires detailed data preparation and logging. However, Instructor provides a built-in logging feature and structured outputs to simplify this. + +## Why Instructor and Distillation are Game Changers + +The library offers two main benefits: + +1. **Efficiency**: Streamlines functions, distilling requirements into model weights and a few lines of code. +2. **Integration**: Eases combining classical machine learning and language models by providing a simple interface that wraps existing functions. + +## Role of Instructor in Simplifying Fine-Tuning + +The `from instructor import Instructions` feature is a time saver. It auto-generates a fine-tuning dataset, making it a breeze to imitate a function's behavior. + +## Logging Output and Running a Finetune +Here's how the logging output would look: ```python { @@ -79,18 +94,14 @@ for _ in range(10): } ``` -## Why Instructor and Distillation are Useful +Run a finetune like this: -Many systems are not as simple as a single `openai.ChatCompletion.create` call, instead we often create objects, do additional processing, validation, error correction, and then return the result. This is a lot of work, and it's easy to make mistakes. Instructor's `distil` feature makes this process easier by: +```bash +instructor jobs create-from-file math_finetunes.jsonl +``` -1. Streamlines complex functions with validations, making them more efficient. -2. Facilitates the integration of classical machine learning with language models. - -By understanding and leveraging these capabilities, you can create powerful, fine-tuned language models with ease. To learn more about how to use the file to finetune a model, check out the [cli](/docs/cli/finetune.md) - -## Next Steps - -This post is mostly a peek of what I've been working on this week. Once we have a model trained I'd like to be able to dynamically swap the implemetnation of a function with a model. This would allow us to do things like: +## Next Steps and Future Plans +Here's a sneak peek of what I'm planning: ```python from instructor import Instructions @@ -99,12 +110,14 @@ instructions = Instructions( name="three_digit_multiply", ) -@instructions.distil(model='gpt-3.5-turbo:finetuned', swap=True) +@instructions.distil(model='gpt-3.5-turbo:finetuned-123', mode="dispatch") def fn(a: int, b: int) -> Multiply: resp = a + b return Multiply(a=a, b=b, result=resp) ``` -Now we can swap out the implementation of `fn` with calling the finetuned model, since we know the response type is still `Multiply` we can use instructor behind the scenes and have it be backwards compatible with the existing code. +With this, you can swap the function implementation, making it backward compatible. You can even imagine using the different models for different tasks or validating and runnign evals by using the original function and comparing it to the distillation. -Now if you're thinking wow, I'd love a backend service to do this for continously, you're in luck! Please check out the survey at [useinstructor.com](https://useinstructor.com) and let us know who you are. \ No newline at end of file +## Conclusion + +We've seen how `Instructor` can make your life easier, from fine-tuning to distillation. Stay tuned for more updates and don't forget to check out the survey at [useinstructor.com](https://useinstructor.com). \ No newline at end of file