|
import marimo |
|
|
|
__generated_with = "0.11.17" |
|
app = marimo.App(width="full") |
|
|
|
|
|
@app.cell |
|
def _(): |
|
import marimo as mo |
|
import pandas as pd |
|
import os |
|
import io |
|
import json |
|
return io, json, mo, os, pd |
|
|
|
|
|
@app.cell |
|
def _(mo): |
|
|
|
|
|
wx_platform_url = "https://api.dataplatform.cloud.ibm.com" |
|
regions = { |
|
"US": "https://us-south.ml.cloud.ibm.com", |
|
"EU": "https://eu-de.ml.cloud.ibm.com", |
|
"GB": "https://eu-gb.ml.cloud.ibm.com", |
|
"JP": "https://jp-tok.ml.cloud.ibm.com", |
|
"AU": "https://au-syd.ml.cloud.ibm.com", |
|
"CA": "https://ca-tor.ml.cloud.ibm.com" |
|
} |
|
|
|
|
|
client_instantiation_form = ( |
|
mo.md(''' |
|
###**watsonx.ai credentials:** |
|
|
|
{wx_region} |
|
|
|
{wx_api_key} |
|
|
|
{project_id} |
|
|
|
''') |
|
.batch( |
|
wx_region = mo.ui.dropdown(regions, label="Select your watsonx.ai region:", value="US", searchable=True), |
|
wx_api_key = mo.ui.text(placeholder="Add your IBM Cloud api-key...", label="IBM Cloud Api-key:", kind="password"), |
|
project_id = mo.ui.text(placeholder="Add your watsonx.ai project_id...", label="Project_ID:", kind="text"), |
|
space_id = mo.ui.text(placeholder="Add your watsonx.ai space_id...", label="Space_ID:", kind="text") |
|
,) |
|
.form(show_clear_button=True, bordered=False) |
|
) |
|
|
|
return client_instantiation_form, regions, wx_platform_url |
|
|
|
|
|
@app.cell |
|
def _(client_instantiation_form, mo): |
|
from ibm_watsonx_ai import APIClient, Credentials |
|
import requests |
|
|
|
def get_iam_token(api_key): |
|
return requests.post( |
|
'https://iam.cloud.ibm.com/identity/token', |
|
headers={'Content-Type': 'application/x-www-form-urlencoded'}, |
|
data={'grant_type': 'urn:ibm:params:oauth:grant-type:apikey', 'apikey': api_key} |
|
).json()['access_token'] |
|
|
|
def setup_task_credentials(project_client): |
|
|
|
existing_credentials = project_client.task_credentials.get_details() |
|
|
|
|
|
if "resources" in existing_credentials and existing_credentials["resources"]: |
|
for cred in existing_credentials["resources"]: |
|
cred_id = project_client.task_credentials.get_id(cred) |
|
project_client.task_credentials.delete(cred_id) |
|
|
|
|
|
return project_client.task_credentials.store() |
|
|
|
if client_instantiation_form.value: |
|
|
|
wx_api_key = client_instantiation_form.value["wx_api_key"] |
|
|
|
wx_credentials = Credentials( |
|
url=client_instantiation_form.value["wx_region"], |
|
api_key=wx_api_key |
|
) |
|
|
|
project_client = APIClient(credentials=wx_credentials, project_id=client_instantiation_form.value["project_id"]) |
|
|
|
|
|
token = get_iam_token(wx_api_key) |
|
task_credentials_details = setup_task_credentials(project_client) |
|
|
|
else: |
|
project_client = None |
|
|
|
task_credentials_details = None |
|
wx_api_key = None |
|
token = None |
|
|
|
client_status = mo.md("### Client Instantiation Status will turn Green When Ready") |
|
|
|
if project_client is not None: |
|
client_callout_kind = "success" |
|
else: |
|
client_callout_kind = "neutral" |
|
return ( |
|
APIClient, |
|
Credentials, |
|
client_callout_kind, |
|
client_status, |
|
get_iam_token, |
|
project_client, |
|
requests, |
|
setup_task_credentials, |
|
task_credentials_details, |
|
token, |
|
wx_api_key, |
|
wx_credentials, |
|
) |
|
|
|
|
|
@app.cell |
|
def _(client_callout_kind, client_instantiation_form, client_status, mo): |
|
client_callout = mo.callout(client_status, kind=client_callout_kind) |
|
|
|
client_stack = mo.hstack([client_instantiation_form, client_callout], align="center", justify="space-around") |
|
|
|
client_stack |
|
return client_callout, client_stack |
|
|
|
|
|
@app.cell |
|
def _(mo, project_client): |
|
if project_client: |
|
|
|
model_specs = project_client.foundation_models.get_model_specs() |
|
resources = model_specs["resources"] |
|
model_id_list = [] |
|
for resource in resources: |
|
model_id_list.append(resource["model_id"]) |
|
model_selection = mo.ui.table( |
|
model_id_list, |
|
selection="single", |
|
label="Select a model to use.", |
|
page_size=30, |
|
initial_selection=[16] |
|
) |
|
else: |
|
model_specs = [] |
|
resources = [] |
|
model_id_list = [] |
|
model_selection = mo.md("**Instantiate a watsonx.ai client with a valid project_id**") |
|
|
|
return model_id_list, model_selection, model_specs, resource, resources |
|
|
|
|
|
@app.cell |
|
def _(mo, model_selection): |
|
from ibm_watsonx_ai.foundation_models import ModelInference |
|
from ibm_watsonx_ai.metanames import GenTextParamsMetaNames as GenParams |
|
|
|
llm_parameters = ( |
|
mo.md(''' |
|
###**LLM parameters:** |
|
|
|
{decoding_method} |
|
|
|
{repetition_penalty} |
|
|
|
{min_tokens} |
|
|
|
{max_tokens} |
|
|
|
{stop_sequences} |
|
''') |
|
.batch( |
|
|
|
decoding_method = mo.ui.dropdown(options=["greedy", "sample"], value="greedy",label="Decoding Method:"), |
|
min_tokens = mo.ui.number(start=1, stop=1, label="Minimum Output Tokens:"), |
|
max_tokens = mo.ui.number(start=1, stop=8096, value=500, label="Maximum Output Tokens:"), |
|
repetition_penalty = mo.ui.number(start=1.0, stop=2.0, step=0.01, label="Repetition Penalty:"), |
|
stop_sequences = mo.ui.text(label="Stopping Sequences:", value="['<|end_of_text|>','</s>']", placeholder="List of Strings, e.g. ['<|end_of_text|>','</s>']", full_width=False) |
|
).form(show_clear_button=True, bordered=True) |
|
) |
|
|
|
|
|
llm_setup = mo.hstack([model_selection, llm_parameters], align="center", justify="space-around") |
|
|
|
llm_setup |
|
return GenParams, ModelInference, llm_parameters, llm_setup |
|
|
|
|
|
@app.cell |
|
def _( |
|
GenParams, |
|
ModelInference, |
|
llm_parameters, |
|
model_selection, |
|
project_client, |
|
): |
|
import ast |
|
|
|
if llm_parameters.value: |
|
params = { |
|
GenParams.DECODING_METHOD: llm_parameters.value['decoding_method'], |
|
GenParams.MAX_NEW_TOKENS: llm_parameters.value['max_tokens'], |
|
GenParams.MIN_NEW_TOKENS: llm_parameters.value['min_tokens'], |
|
GenParams.REPETITION_PENALTY: llm_parameters.value['repetition_penalty'], |
|
GenParams.STOP_SEQUENCES: ast.literal_eval(llm_parameters.value['stop_sequences']), |
|
GenParams.RETURN_OPTIONS: { |
|
'input_text': False, |
|
'generated_tokens': False, |
|
'input_tokens': True, |
|
'token_logprobs': False |
|
} |
|
} |
|
|
|
inf_model = ModelInference(api_client=project_client, model_id=model_selection.value[0], params=params) |
|
else: |
|
params = {} |
|
inf_model = None |
|
return ast, inf_model, params |
|
|
|
|
|
@app.cell |
|
def _(mo): |
|
prompt_template_mistral = """[INST] write your prompt here [/INST]""" |
|
|
|
prompt_template_llama = """<|start_header_id|>user<|end_header_id|>\n\n write your prompt here <|eot_id|><|start_header_id|>assistant<|end_header_id|>\n\n""" |
|
|
|
|
|
templates = { |
|
"mistral": prompt_template_mistral, |
|
"llama": prompt_template_llama |
|
} |
|
|
|
template_selector = mo.ui.dropdown(templates, value="mistral", label="Select Prompt Template with Syntax:") |
|
return ( |
|
prompt_template_llama, |
|
prompt_template_mistral, |
|
template_selector, |
|
templates, |
|
) |
|
|
|
|
|
@app.cell |
|
def _(mo, template_selector): |
|
prompt_editor = ( |
|
mo.md(''' |
|
#### **Create your prompt here by editing the template:** |
|
|
|
{editor} |
|
|
|
''') |
|
.batch( |
|
editor = mo.ui.code_editor(value=template_selector.value, language="python", min_height=50) |
|
) |
|
.form(show_clear_button=True, bordered=False) |
|
) |
|
return (prompt_editor,) |
|
|
|
|
|
@app.cell |
|
def _(mo, prompt_editor, template_selector): |
|
prompt_setup = mo.vstack([template_selector, prompt_editor]) |
|
prompt_setup |
|
return (prompt_setup,) |
|
|
|
|
|
@app.cell |
|
def _(mo, prompt_editor): |
|
_ = prompt_editor.value |
|
|
|
if prompt_editor.value is not None: |
|
prompt_printout = mo.md(f"**Current prompt template:**\n\n {prompt_editor.value['editor']}") |
|
else: |
|
prompt_printout = mo.md(f"**Submit a prompt template.**") |
|
|
|
prompt_printout |
|
return (prompt_printout,) |
|
|
|
|
|
@app.cell |
|
def _(inf_model, params, process_with_llm, prompt_editor): |
|
_ = prompt_editor.value |
|
|
|
if prompt_editor.value is not None: |
|
prompt_response = process_with_llm(inf_model, prompt_template=prompt_editor.value['editor'], params=params, return_full_json_response=False) |
|
prompt_response_full = process_with_llm(inf_model, prompt_template=prompt_editor.value['editor'], params=params, return_full_json_response=True) |
|
else: |
|
prompt_response = [] |
|
prompt_response_full = [] |
|
return prompt_response, prompt_response_full |
|
|
|
|
|
@app.cell |
|
def _(mo, prompt_response, prompt_response_full): |
|
mo.vstack([mo.md(f"{prompt_response}"),prompt_response_full], align="center",justify="space-around") |
|
return |
|
|
|
|
|
@app.cell |
|
def _(): |
|
def process_with_llm(inf_model, prompt_template, params, return_full_json_response=False): |
|
""" |
|
Process a prompt with an LLM model. |
|
|
|
Returns full JSON response or just text based on return_full_json_response parameter. |
|
""" |
|
|
|
if not inf_model: |
|
print("Missing required inference model") |
|
return None |
|
|
|
|
|
if hasattr(prompt_template, 'get') and prompt_template.get('value'): |
|
prompt_template = prompt_template['value'] |
|
|
|
try: |
|
|
|
if return_full_json_response: |
|
return inf_model.generate(prompt=prompt_template, params=params) |
|
else: |
|
return inf_model.generate_text(prompt=prompt_template, params=params) |
|
|
|
except Exception as e: |
|
print(f"Error during inference: {str(e)}") |
|
return None |
|
return (process_with_llm,) |
|
|
|
|
|
if __name__ == "__main__": |
|
app.run() |
|
|