Skip to content

Commit b1d1018

Browse files
authored
Merging pull request #16877
1 parent 4afc5a3 commit b1d1018

File tree

9 files changed

+94
-34
lines changed

9 files changed

+94
-34
lines changed

components/lamini/actions/create-fine-tune-job/create-fine-tune-job.mjs

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default {
66
key: "lamini-create-fine-tune-job",
77
name: "Create Fine-Tune Job",
88
description: "Create a fine-tuning job with a dataset. [See the documentation](https://docs.lamini.ai/api/).",
9-
version: "0.0.1",
9+
version: "0.0.2",
1010
type: "action",
1111
props: {
1212
app,
@@ -49,6 +49,13 @@ export default {
4949
description: "A human-readable name for the fine-tuned model.",
5050
optional: true,
5151
},
52+
waitForCompletion: {
53+
type: "boolean",
54+
label: "Wait for Completion",
55+
description: "If set to `true`, the action will wait and poll until the fine-tuning job is `COMPLETED`. If is set to `false`, it will return immediately after creating the job.",
56+
default: false,
57+
optional: true,
58+
},
5259
},
5360
methods: {
5461
createFineTuneJob(args = {}) {
@@ -69,35 +76,87 @@ export default {
6976
gpuConfig,
7077
isPublic,
7178
customModelName,
79+
waitForCompletion,
7280
} = this;
7381

74-
const { upload_base_path: uploadBasePath } =
75-
await app.getUploadBasePath({
82+
const MAX_RETRIES = 15;
83+
const DELAY = 1000 * 30; // 30 seconds
84+
const { run } = $.context;
85+
86+
// First run: Create the fine-tune job
87+
if (run.runs === 1) {
88+
const { upload_base_path: uploadBasePath } =
89+
await app.getUploadBasePath({
90+
$,
91+
});
92+
93+
await app.getExistingDataset({
7694
$,
95+
data: {
96+
dataset_id: datasetId,
97+
upload_base_path: uploadBasePath,
98+
},
7799
});
78100

79-
await app.getExistingDataset({
80-
$,
81-
data: {
82-
dataset_id: datasetId,
83-
upload_base_path: uploadBasePath,
84-
},
85-
});
101+
const response = await createFineTuneJob({
102+
$,
103+
data: {
104+
model_name: modelName,
105+
dataset_id: datasetId,
106+
upload_file_path: `${uploadBasePath}/${datasetId}.jsonlines`,
107+
finetune_args: utils.parseJson(fineTuneArgs),
108+
gpu_config: utils.parseJson(gpuConfig),
109+
is_public: isPublic,
110+
custom_model_name: customModelName,
111+
},
112+
});
113+
114+
$.export("$summary", `Successfully created a fine-tune job with ID \`${response.job_id}\`.`);
115+
116+
// If user doesn't want to wait, return immediately
117+
if (!waitForCompletion) {
118+
return response;
119+
}
120+
121+
// Store job_id for polling and start rerun
122+
$.flow.rerun(DELAY, {
123+
jobId: response.job_id,
124+
}, MAX_RETRIES);
125+
return response;
126+
}
86127

87-
const response = await createFineTuneJob({
128+
// Subsequent runs: Poll for job status
129+
if (run.runs > MAX_RETRIES) {
130+
throw new Error("Max retries exceeded - fine-tuning job may still be running");
131+
}
132+
133+
const { jobId } = run.context;
134+
135+
// Poll for status
136+
const statusResponse = await app.getJobStatus({
88137
$,
89-
data: {
90-
model_name: modelName,
91-
dataset_id: datasetId,
92-
upload_file_path: `${uploadBasePath}/${datasetId}.jsonlines`,
93-
finetune_args: utils.parseJson(fineTuneArgs),
94-
gpu_config: utils.parseJson(gpuConfig),
95-
is_public: isPublic,
96-
custom_model_name: customModelName,
97-
},
138+
jobId,
98139
});
99140

100-
$.export("$summary", `Successfully created a fine-tune job with ID \`${response.job_id}\`.`);
101-
return response;
141+
// If job is completed, return the final status
142+
if (statusResponse.status === "COMPLETED") {
143+
$.export("$summary", `Fine-tuning job \`${jobId}\` completed successfully.`);
144+
return statusResponse;
145+
}
146+
147+
// If job failed, throw error
148+
if (statusResponse.status === "FAILED") {
149+
throw new Error(`Fine-tuning job \`${jobId}\` failed.`);
150+
}
151+
152+
// Otherwise, continue polling
153+
$.flow.rerun(DELAY, {
154+
jobId,
155+
}, MAX_RETRIES);
156+
return {
157+
status: statusResponse.status,
158+
jobId,
159+
message: `Job is still running. Current status: ${statusResponse.status}`,
160+
};
102161
},
103162
};

components/lamini/actions/evaluate-job/evaluate-job.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ export default {
44
key: "lamini-evaluate-job",
55
name: "Evaluate Job",
66
description: "Evaluate a fine-tuning job by job ID. [See the documentation](https://docs.lamini.ai/api/).",
7-
version: "0.0.1",
7+
version: "0.0.2",
88
type: "action",
99
props: {
1010
app,
1111
jobId: {
1212
propDefinition: [
1313
app,
1414
"jobId",
15+
() => ({
16+
filter: ({ status }) => status === "COMPLETED",
17+
}),
1518
],
1619
description: "The ID of the fine-tuning job to evaluate.",
1720
},

components/lamini/actions/generate-completion/generate-completion.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "lamini-generate-completion",
66
name: "Generate Completion",
77
description: "Generate completions using a Lamini model. [See the documentation](https://docs.lamini.ai/api/).",
8-
version: "0.0.1",
8+
version: "0.0.2",
99
type: "action",
1010
props: {
1111
app,

components/lamini/actions/get-batch-completions/get-batch-completions.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "lamini-get-batch-completions",
66
name: "Get Batch Completions",
77
description: "Retrieve the results of a batch completion request from Lamini. [See the documentation](https://docs.lamini.ai/api/).",
8-
version: "0.0.1",
8+
version: "0.0.2",
99
type: "action",
1010
props: {
1111
app,

components/lamini/actions/upload-dataset/upload-dataset.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "lamini-upload-dataset",
88
name: "Upload Dataset",
99
description: "Upload a dataset to Lamini for training.",
10-
version: "0.0.1",
10+
version: "0.0.2",
1111
type: "action",
1212
props: {
1313
app,
@@ -19,12 +19,12 @@ export default {
1919
inputKey: {
2020
type: "string",
2121
label: "Input Key",
22-
description: "Key of the JSON dictionary to use as the input. For CSV files, this should be a column header. Eg. `question`.",
22+
description: "Key of the JSON dictionary to use as the input. Eg. `question`.",
2323
},
2424
outputKey: {
2525
type: "string",
2626
label: "Output Key",
27-
description: "Key of the JSON dictionary to use as the output. For CSV files, this should be a column header. Eg. `answer`.",
27+
description: "Key of the JSON dictionary to use as the output. Eg. `answer`.",
2828
optional: true,
2929
},
3030
isPublic: {

components/lamini/lamini.app.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ export default {
3838
type: "string",
3939
label: "Job ID",
4040
description: "The ID of the fine-tuning job to use.",
41-
async options() {
41+
async options({ filter = () => true }) {
4242
const jobs = await this.listTrainedJobs();
4343
return jobs
44-
.filter(({ status }) => status === "COMPLETED")
44+
.filter(filter)
4545
.map(({
4646
custom_model_name: label,
4747
job_id: value,

components/lamini/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/lamini",
3-
"version": "0.1.0",
3+
"version": "0.1.1",
44
"description": "Pipedream Lamini Components",
55
"main": "lamini.app.mjs",
66
"keywords": [

components/lamini/sources/get-job-status/get-job-status.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default {
88
key: "lamini-get-job-status",
99
name: "New Job Status",
1010
description: "Emit new events with the status of a training job. [See the documentation](https://docs.lamini.ai/api/).",
11-
version: "0.0.1",
11+
version: "0.0.2",
1212
type: "source",
1313
props: {
1414
app,

pnpm-lock.yaml

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)