This example outlines the general process of pretraining and fine-tuning a model using Snowflake Cortex AI. It assumes you have a basic understanding of Snowflake and Python. Actual code and specific configurations depend on the model type and dataset.
ACCOUNTADMIN or a custom role granted the appropriate permissions).Your data is the foundation. It needs to be well-structured and appropriately formatted for the model you are using. Example data structure might look like this (this is just a *template* and needs modification):
Sample Data:
id | text | label ---|---|--- 1 | "This is a great product." | positive 2 | "The service was terrible." | negative 3 | "The food was okay." | neutral
Pretraining involves training the model on a large, general dataset to learn underlying language patterns. Snowflake Cortex AI doesn't directly handle all pretraining tasks, but provides tools to orchestrate the process, which often involves external compute. Here’s a conceptual outline:
-- Example (Conceptual - needs adaptation)
CREATE OR REPLACE TASK pretraining_task
WAREHOUSE = MY_WAREHOUSE
SCHEDULE = '10:00 UTC' -- Example schedule
AS
CALL SNOWFLAKE.APP_MAINTENANCE.EXECUTE_STAGE_TASK(
stage_name = 'MY_STAGE', -- Your stage to hold the Python script
procedure_name = 'MY_PYTHON_SCRIPT'
);
Fine-tuning adapts the pretrained model to your specific task using your labeled dataset. This is where Snowflake Cortex AI shines.
-- Example (Conceptual - Highly Simplified)
CREATE OR REPLACE FUNCTION fine_tune_model(model_name VARCHAR, training_table VARCHAR, epochs INTEGER)
RETURNS VARCHAR -- Returns a status message
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-connector-python', 'transformers')
HANDLER = 'path/to/your/fine_tuning_script.py'
;
-- Example of calling the function:
SELECT fine_tune_model('my_pretrained_model', 'MY_DATABASE.MY_SCHEMA.TRAINING_DATA', 10);
import snowflake
from transformers import AutoModelForSequenceClassification, Trainer, TrainingArguments, Dataset
def fine_tune_model(model_name, training_table, epochs):
# Connect to Snowflake
ctx = snowflake.connector.connect(
account = 'YOUR_SNOWFLAKE_ACCOUNT',
user = 'YOUR_SNOWFLAKE_USER',
password = 'YOUR_SNOWFLAKE_PASSWORD',
database = 'MY_DATABASE',
schema = 'MY_SCHEMA'
)
cursor = ctx.cursor()
# Load data from Snowflake
query = f"SELECT text, label FROM {training_table}"
cursor.execute(query)
data = []
for row in cursor:
data.append({'text': row[0], 'label': row[1]})
# Convert to a Transformers Dataset
dataset = Dataset.from_list(data)
# Load pre-trained model
model = AutoModelForSequenceClassification.from_pretrained(model_name)
# Define training arguments
training_args = TrainingArguments(
output_dir="./results",
num_train_epochs=epochs,
per_device_train_batch_size=8,
per_device_eval_batch_size=16,
# other arguments...
)
# Define Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=dataset,
# eval_dataset=eval_dataset, # If you have a validation dataset
)
# Train the model
trainer.train()
# Save the fine-tuned model (e.g., to Snowflake's internal storage)
# This often requires custom Snowflake integration or using Snowflake Object Storage
ctx.close()
return "Fine-tuning complete. Model saved (implementation depends on your Snowflake setup)"
After fine-tuning, you can deploy the model and use it for inference. Cortex AI provides features for model deployment and serving, including:
Cortex Fine-Tuning is a serverless service inside Snowflake that runs supervised fine-tuning (SFT) on a supported base LLM using a Snowflake table of prompt/completion pairs. You call SNOWFLAKE.CORTEX.FINETUNE('CREATE', model_name, base_model, training_table, validation_table) from SQL, monitor with FINETUNE('DESCRIBE', job_id), and once complete reference the new model name in CORTEX.COMPLETE(). No notebooks, no GPUs, no data egress — the training data never leaves the Snowflake account.
The supported base models change as Snowflake adds them, but typically include Mistral 7B, Mixtral 8x7B, Llama 3 8B/70B, and Snowflake's own Arctic family. Region availability matters — not every base model is in every Snowflake region, so check the cross-region inference docs and consider enabling cross-region inference for your account before launching a job. Closed-source models (GPT-4, Claude) cannot be fine-tuned through Cortex; for those you'd use the vendor's hosted fine-tuning service.
Land a Snowflake table with two columns — prompt and completion — typically a few hundred to a few thousand high-quality examples. Hold out a separate validation table to monitor overfitting. Quality dominates quantity: deduplicate, strip PII you don't want memorized, and balance class distributions if you're fine-tuning for classification-like behavior. The whole pipeline (curation, train, eval) stays in SQL or Snowpark, so lineage and access controls are inherited from the source tables.
Run the held-out validation set through both the base model and the fine-tuned model with CORTEX.COMPLETE(), then score with task-appropriate metrics: exact-match or BLEU for short structured outputs, ROUGE for summaries, or LLM-as-judge using Cortex itself or an external Claude/GPT to rate factuality and helpfulness on a 1-5 scale. Persist results in a Snowflake table so you can compare across fine-tuning runs and pick the best version. Track cost-per-correct-answer alongside raw accuracy — a small base model fine-tuned often beats a larger zero-shot model on dollars per quality unit.
RAG first, fine-tune second. Use RAG when the task is "answer questions over my documents" — knowledge changes daily, citations matter, and embeddings + Cortex Search solve it cleanly. Fine-tune when the task is about style, format, or a narrow skill the base model handles inconsistently — e.g., always emit JSON in a specific schema, write SQL in your team's dialect, or classify support tickets into your taxonomy. The two combine well: a fine-tuned model that's good at your output format consuming RAG context.
Treat fine-tuned models as code artifacts: every training run is parameterized by a Snowflake task that snapshots the source data, computes a content hash, runs FINETUNE('CREATE', ...) with a versioned model name (support_classifier_v37), and runs the eval suite immediately after. Promote with an alias view or a config table that the application reads (SELECT current_model FROM ml_config WHERE use_case = 'support') — flipping the alias is the production cutover and rollback is one UPDATE. Track per-model invocation cost via SNOWFLAKE.ACCOUNT_USAGE.CORTEX_FUNCTIONS_USAGE_HISTORY and retire models nobody calls.