Mistral Fine-tuning API

Finetuning

Check out the docs: https://docs.mistral.ai/capabilities/finetuning/

!pip install mistralai pandas

Prepare the dataset

In this example, let’s use the ultrachat_200k dataset. We load a chunk of the data into Pandas Dataframes, split the data into training and validation, and save the data into the required jsonl format for fine-tuning.

import pandas as pd
df = pd.read_parquet('https://huggingface.co/datasets/HuggingFaceH4/ultrachat_200k/resolve/main/data/test_gen-00000-of-00001-3d4cd8309148a71f.parquet')

df_train=df.sample(frac=0.995,random_state=200)
df_eval=df.drop(df_train.index)

df_train.to_json("ultrachat_chunk_train.jsonl", orient="records", lines=True)
df_eval.to_json("ultrachat_chunk_eval.jsonl", orient="records", lines=True)
!ls -lh

Reformat dataset

If you upload this ultrachat_chunk_train.jsonl to Mistral API, you might encounter an error message “Invalid file format” due to data formatting issues. To reformat the data into the correct format, you can download the reformat_dataset.py script and use it to validate and reformat both the training and evaluation data:

# download the validation and reformat script
!wget https://raw.githubusercontent.com/mistralai/mistral-finetune/main/utils/reformat_data.py
# validate and reformat the training data
!python reformat_data.py ultrachat_chunk_train.jsonl
# validate the reformat the eval data
!python reformat_data.py ultrachat_chunk_eval.jsonl
df_train.iloc[3674]['messages']

Upload dataset

from mistralai import Mistral
import os

api_key = os.environ["MISTRAL_API_KEY"]

client = Mistral(api_key=api_key)

ultrachat_chunk_train = client.files.upload(file={
    "file_name": "ultrachat_chunk_train.jsonl",
    "content": open("ultrachat_chunk_train.jsonl", "rb"),
})
ultrachat_chunk_eval = client.files.upload(file={
    "file_name": "ultrachat_chunk_eval.jsonl",
    "content": open("ultrachat_chunk_eval.jsonl", "rb"),
})
import json
def pprint(obj):
    print(json.dumps(obj.dict(), indent=4))
pprint(ultrachat_chunk_train)
pprint(ultrachat_chunk_eval)

Create a fine-tuning job

created_jobs = client.fine_tuning.jobs.create(
    model="open-mistral-7b",
    training_files=[{"file_id": ultrachat_chunk_train.id, "weight": 1}],
    validation_files=[ultrachat_chunk_eval.id],
    hyperparameters={
    "training_steps": 10,
    "learning_rate":0.0001
    },
    auto_start=True
)
created_jobs
pprint(created_jobs)
jobs = client.fine_tuning.jobs.list()
print(jobs)
retrieved_jobs = client.fine_tuning.jobs.get(job_id = created_jobs.id)
retrieved_jobs
import time

retrieved_job = client.fine_tuning.jobs.get(job_id = created_jobs.id)
while retrieved_job.status in ["RUNNING", "QUEUED"]:
    retrieved_job = client.fine_tuning.jobs.get(job_id = created_jobs.id)
    pprint(retrieved_job)
    print(f"Job is {retrieved_job.status}, waiting 10 seconds")
    time.sleep(10)

# List jobs
jobs = client.fine_tuning.jobs.list()
pprint(jobs)
# Retrieve a jobs
retrieved_jobs = client.fine_tuning.jobs.get(job_id = created_jobs.id)
pprint(retrieved_jobs)

Use a fine-tuned model

chat_response = client.chat.complete(
    model = retrieved_jobs.fine_tuned_model,
    messages = [{"role":'user', "content":'What is the best French cheese?'}]
)
pprint(chat_response)

Integration with Weights and Biases

We can also offer support for integration with Weights & Biases (W&B) to monitor and track various metrics and statistics associated with our fine-tuning jobs. To enable integration with W&B, you will need to create an account with W&B and add your W&B information in the “integrations” section in the job creation request:

client.fine_tuning.jobs.create(
    model="open-mistral-7b",
    training_files=[{"file_id": ultrachat_chunk_train.id, "weight": 1}],
    validation_files=[ultrachat_chunk_eval.id],
    hyperparameters={"training_steps": 10, "learning_rate": 0.0001},
    integrations=[
        {
            "project": "<value>",
            "api_key": "<value>",
        }
    ]
)