> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portkey.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Fine-tune

> Fine-tune your models with Bedrock

### Upload a file

Please follow to the bedrock file upload [guide](/docs/aigw/integrations/llms/bedrock/files) for more details.

### Create a fine-tuning job

<Tabs>
  <Tab title="REST API">
    ```sh theme={"system"}
    curl \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <api_key>' \
    --header 'x-portkey-aws-s3-bucket: <s3_bucket>' \
    --data '{
      "model": "@provider/<model_id>",
      "model_type": "text", #chat or text
      "suffix": "<finetune_model_name>",
      "training_file": "<s3_path.jsonl>",
      "role_arn": "<role_arn>",
      "job_name": "<job_name>",
      "hyperparameters": {
        "n_epochs": 1
      }
    }' \
    'https://aigw.portkey.ai/v1/fine_tuning/jobs'
    ```
  </Tab>

  <Tab title="OpenAI Python">
    ```python theme={"system"}
    from openai import OpenAI

    openai = OpenAI(
        api_key="PORTKEY_API_KEY",
        base_url="https://aigw.portkey.ai/v1"
    )

    fine_tune_job = openai.fine_tuning.jobs.create(
        training_file="file_id", # encoded s3 file URI of the training data.
        model="@PROVIDER/model_id", # bedrock modelId for fine-tuning
        hyperparameters={
          "n_epochs": 1
        },
        role_arn="role_arn", # service role arn for bedrock job to assume when running.
        job_name="job_name", # name for the job, optional will created random if not provided.
        validation_file="file_id", # optional, must be encoded s3 file URI.
        suffix="finetuned_model_name",
        model_type="text" # optional, chat or text.
      )

    print(fine_tune_job)
    ```
  </Tab>

  <Tab title="OpenAI NodeJS">
    ```typescript theme={"system"}
    import OpenAI from 'openai'; // We're using the v4 SDK

    const openai = new OpenAI({
      apiKey: "PORTKEY_API_KEY",  // defaults to process.env["PORTKEY_API_KEY"]
      baseURL: "https://aigw.portkey.ai/v1"
    });

    (async () => {
        const fine_tune_job = await openai.fineTuning.jobs.create({
          training_file: "file_id", // encoded s3 file URI of the training data.
          model: "@PROVIDER/model_id", // ex: `modelId` from bedrock for fine-tuning
          hyperparameters: {
            "n_epochs": 1
          },
          role_arn: "role_arn", // service role arn for bedrock job to assume when running.
          job_name: "job_name", // name for the job, optional will created random if not provided.
          validation_file: "file_id", // optional, must be encoded s3 file URI.
          suffix: "finetuned_model_name",
          model_type: "text" // optional, chat or text.
        });

      console.log(fine_tune_job)
    })();
    ```
  </Tab>
</Tabs>

**Notes:**

* Bedrock fine-tuning dataset format is a little bit different from OpenAI's fine-tuning dataset format.
* `model_type` field is required for the dataset transformation, currently gateway does the following dataset transformation:
  * `chat` -> `text-to-text`
  * `chat` -> `chat`.
* `model` param should be the `ModelID` that is required for fine-tuning not for the inference. `ModelID` is different for inference and fine-tuning.

> List of supported finetune models and their IDs are available at [Bedrock documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization.html)

## List Fine-tuning Jobs

<Tabs>
  <Tab title="REST API">
    ```sh theme={"system"}
    curl \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <api_key>' \
    --header 'x-portkey-provider: @provider' \
    'https://aigw.portkey.ai/v1/fine_tuning/jobs?limit=10'
    ```
  </Tab>

  <Tab title="OpenAI Python">
    ```python theme={"system"}
    from openai import OpenAI

    openai = OpenAI(
        api_key="PORTKEY_API_KEY",
        base_url="https://aigw.portkey.ai/v1",
        default_headers={"x-portkey-provider": "@PROVIDER"}
    )

    # List all fine-tuning jobs
    jobs = openai.fine_tuning.jobs.list(
        limit=10  # Optional: Number of jobs to retrieve (default: 20)
    )

    print(jobs)
    ```
  </Tab>

  <Tab title="OpenAI NodeJS">
    ```typescript theme={"system"}
    import OpenAI from 'openai';

    const openai = new OpenAI({
        apiKey: "PORTKEY_API_KEY",
        baseURL: "https://aigw.portkey.ai/v1",
        defaultHeaders: { "x-portkey-provider": "@PROVIDER" }
    });

    (async () => {
        // List all fine-tuning jobs
        const jobs = await openai.fineTuning.jobs.list({
            limit: 10  // Optional: Number of jobs to retrieve (default: 20)
        });

        console.log(jobs);
    })();
    ```
  </Tab>
</Tabs>

## Retrieve Fine-tuning Job

<Tabs>
  <Tab title="REST API">
    ```sh theme={"system"}
    curl \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <api_key>' \
    --header 'x-portkey-provider: @provider' \
    'https://aigw.portkey.ai/v1/fine_tuning/jobs/<job_id>'
    ```
  </Tab>

  <Tab title="OpenAI Python">
    ```python theme={"system"}
    from openai import OpenAI

    openai = OpenAI(
        api_key="PORTKEY_API_KEY",
        base_url="https://aigw.portkey.ai/v1",
        default_headers={"x-portkey-provider": "@PROVIDER"}
    )

    # Retrieve a specific fine-tuning job
    job = openai.fine_tuning.jobs.retrieve(
        fine_tuning_job_id="job_id"  # The ID of the fine-tuning job to retrieve
    )

    print(job)
    ```
  </Tab>

  <Tab title="OpenAI NodeJS">
    ```typescript theme={"system"}
    import OpenAI from 'openai';

    const openai = new OpenAI({
        apiKey: "PORTKEY_API_KEY",
        baseURL: "https://aigw.portkey.ai/v1",
        defaultHeaders: { "x-portkey-provider": "@PROVIDER" }
    });

    (async () => {
        // Retrieve a specific fine-tuning job
        const job = await openai.fineTuning.jobs.retrieve(
            "job_id"  // The ID of the fine-tuning job to retrieve
        );

        console.log(job);
    })();
    ```
  </Tab>
</Tabs>

## Cancel Fine-tuning Job

<Tabs>
  <Tab title="REST API">
    ```sh theme={"system"}
    curl \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <api_key>' \
    --header 'x-portkey-provider: @provider' \
    'https://aigw.portkey.ai/v1/fine_tuning/jobs/<job_id>/cancel'
    ```
  </Tab>

  <Tab title="OpenAI Python">
    ```python theme={"system"}
    from openai import OpenAI

    openai = OpenAI(
        api_key="PORTKEY_API_KEY",
        base_url="https://aigw.portkey.ai/v1",
        default_headers={"x-portkey-provider": "@PROVIDER"}
    )

    # Cancel a fine-tuning job
    cancelled_job = openai.fine_tuning.jobs.cancel(
        fine_tuning_job_id="job_id"  # The ID of the fine-tuning job to cancel
    )

    print(cancelled_job)
    ```
  </Tab>

  <Tab title="OpenAI NodeJS">
    ```typescript theme={"system"}
    import OpenAI from 'openai';

    const openai = new OpenAI({
        apiKey: "PORTKEY_API_KEY",
        baseURL: "https://aigw.portkey.ai/v1",
        defaultHeaders: { "x-portkey-provider": "@PROVIDER" }
    });

    (async () => {
        // Cancel a fine-tuning job
        const cancelledJob = await openai.fineTuning.jobs.cancel(
            "job_id"  // The ID of the fine-tuning job to cancel
        );

        console.log(cancelledJob);
    })();
    ```
  </Tab>
</Tabs>

## References

* Fine-tune Support types for models: [Link](https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-prepare.html#model-customization-data-support)
* Fine-tuning Documentation: [Link](https://docs.aws.amazon.com/bedrock/latest/userguide/custom-models.html)


## Related topics

- [Fine-tune](/docs/aigw/integrations/llms/vertex-ai/fine-tuning.md)
- [Data Service](/docs/aigw/changelog/data-service.md)
