From 2a171e87fcac0c966672460c2f73bf91e49d8131 Mon Sep 17 00:00:00 2001 From: Siddharth Balyan Date: Wed, 17 Apr 2024 18:49:26 +0530 Subject: [PATCH] remove model surgery notebooks --- model-serving/notebooks/model_inference.ipynb | 217 --- .../notebooks/model_post_surgery.ipynb | 1632 ----------------- model-serving/notebooks/model_quantise.ipynb | 62 - model-serving/notebooks/model_surgery.ipynb | 1554 ---------------- .../notebooks/process_dataset-Copy1.ipynb | 697 ------- .../notebooks/process_dataset-Copy2.ipynb | 726 -------- model-serving/notebooks/process_dataset.ipynb | 731 -------- model-serving/notebooks/train_xgboost.ipynb | 491 ----- .../notebooks/visualize_dataset.ipynb | 510 ------ 9 files changed, 6620 deletions(-) delete mode 100644 model-serving/notebooks/model_inference.ipynb delete mode 100644 model-serving/notebooks/model_post_surgery.ipynb delete mode 100644 model-serving/notebooks/model_quantise.ipynb delete mode 100644 model-serving/notebooks/model_surgery.ipynb delete mode 100644 model-serving/notebooks/process_dataset-Copy1.ipynb delete mode 100644 model-serving/notebooks/process_dataset-Copy2.ipynb delete mode 100644 model-serving/notebooks/process_dataset.ipynb delete mode 100644 model-serving/notebooks/train_xgboost.ipynb delete mode 100644 model-serving/notebooks/visualize_dataset.ipynb diff --git a/model-serving/notebooks/model_inference.ipynb b/model-serving/notebooks/model_inference.ipynb deleted file mode 100644 index d830d41f6..000000000 --- a/model-serving/notebooks/model_inference.ipynb +++ /dev/null @@ -1,217 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo-awq\",\n", - " dtype=\"float16\",\n", - " enforce_eager=True,\n", - " max_model_len=8192,\n", - " max_num_seqs=1,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "WARNING 03-13 16:00:37 config.py:549] Casting torch.bfloat16 to torch.float16.\n", - "WARNING 03-13 16:00:37 config.py:177] awq quantization is not fully optimized yet. The speed can be slower than non-quantized models.\n", - "INFO 03-13 16:00:37 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo-awq', tokenizer='julep-ai/samantha-1-turbo-awq', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.float16, max_seq_len=8192, download_dir=None, load_format=auto, tensor_parallel_size=1, disable_custom_all_reduce=False, quantization=awq, enforce_eager=True, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 03-13 16:00:38 weight_utils.py:164] Using model weights format ['*.safetensors']\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "c77b406c438b4f04be5206613d0e93d3", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "model.safetensors: 0%| | 0.00/4.15G [00:00user\\nWhat is the meaning of life?<|im_end|><|im_start|>\"\n", - "\n", - "sampling_params = SamplingParams(temperature=0.1, max_tokens=200)\n", - "output = engine.generate(prompt, sampling_params, uuid4())" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 03-13 16:20:57 async_llm_engine.py:431] Received request 39cbad1d-71c2-40dd-80c4-cf74fade2fb2: prompt: '<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0.1, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=200, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user', token_ids=[2188], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n', token_ids=[2188, 13], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The', token_ids=[2188, 13, 415], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning', token_ids=[2188, 13, 415, 5746], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of', token_ids=[2188, 13, 415, 5746, 302], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life', token_ids=[2188, 13, 415, 5746, 302, 1411], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is', token_ids=[2188, 13, 415, 5746, 302, 1411, 349], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosoph', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745], cumulative_logprob=-2.7418097943154862e-06, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996], cumulative_logprob=-1.5735537772343378e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369], cumulative_logprob=-1.859655662883597e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659], cumulative_logprob=-1.859655662883597e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750], cumulative_logprob=-1.859655662883597e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been deb', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665], cumulative_logprob=-1.859655662883597e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601], cumulative_logprob=-1.859655662883597e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354], cumulative_logprob=-3.755065358745924e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997], cumulative_logprob=-3.755065358745924e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries.', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723], cumulative_logprob=-3.755065358745924e-05, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Var', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760], cumulative_logprob=-0.005038609455596088, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925], cumulative_logprob=-0.005038609455596088, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosoph', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829], cumulative_logprob=-0.005038609455596088, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404], cumulative_logprob=-0.005038609455596088, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304], cumulative_logprob=-0.005055298616071013, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553], cumulative_logprob=-0.034888216812987594, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337], cumulative_logprob=-0.034888216812987594, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506], cumulative_logprob=-0.034888216812987594, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373], cumulative_logprob=-0.034909316635321375, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581], cumulative_logprob=-0.034909316635321375, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194], cumulative_logprob=-0.28726820025462985, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298], cumulative_logprob=-0.29603977996725916, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456], cumulative_logprob=-0.29603977996725916, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996], cumulative_logprob=-0.29603977996725916, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question.', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723], cumulative_logprob=-0.29604001838580984, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909], cumulative_logprob=-0.29604001838580984, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298], cumulative_logprob=-0.2967498960844921, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300], cumulative_logprob=-0.29676134011080535, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079], cumulative_logprob=-0.29676134011080535, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness,', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725], cumulative_logprob=-0.312795570700672, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312], cumulative_logprob=-0.31281786258861644, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663], cumulative_logprob=-0.31281786258861644, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091], cumulative_logprob=-0.3129073847560164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378], cumulative_logprob=-0.3129073847560164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349], cumulative_logprob=-0.3129073847560164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298], cumulative_logprob=-0.3129073847560164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951], cumulative_logprob=-0.3130884472668356, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298], cumulative_logprob=-0.31626616180093947, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190], cumulative_logprob=-0.3323003923908061, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442], cumulative_logprob=-0.3323003923908061, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298], cumulative_logprob=-0.3323003923908061, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619], cumulative_logprob=-0.8155689513698405, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264], cumulative_logprob=-1.1318141496196574, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948], cumulative_logprob=-1.1321208280898816, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541], cumulative_logprob=-1.132120947299164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal.', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723], cumulative_logprob=-1.132120947299164, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ult', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately,', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411], cumulative_logprob=-1.1321211857177147, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349], cumulative_logprob=-1.132122377809928, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subject', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817], cumulative_logprob=-1.132126073291083, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495], cumulative_logprob=-1.132126073291083, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304], cumulative_logprob=-1.132126073291083, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541], cumulative_logprob=-1.132210946703644, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204], cumulative_logprob=-1.132210946703644, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652], cumulative_logprob=-5.519739366198273, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235], cumulative_logprob=-5.519749498936953, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual beliefs', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235, 16415], cumulative_logprob=-5.519789552457887, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual beliefs and', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235, 16415, 304], cumulative_logprob=-5.529545460969466, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual beliefs and values', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235, 16415, 304, 3069], cumulative_logprob=-5.529545460969466, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual beliefs and values.', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235, 16415, 304, 3069, 28723], cumulative_logprob=-5.529545460969466, logprobs=None, finish_reason=None)], finished=False, lora_request=None)\n", - "RequestOutput(request_id=39cbad1d-71c2-40dd-80c4-cf74fade2fb2, prompt='<|im_start|>user\\nWhat is the meaning of life?<|im_end|><|im_start|>', prompt_token_ids=[1, 32001, 2188, 13, 3195, 349, 272, 5746, 302, 1411, 28804, 32000, 32001], prompt_logprobs=None, outputs=[CompletionOutput(index=0, text=' user\\n The meaning of life is a philosophical question that has been debated for centuries. Various philosophers and religious texts have offered different answers to this question. Some believe that the meaning of life is to find happiness, while others believe it is to contribute to society or to achieve a specific goal. Ultimately, the meaning of life is subjective and can vary from person to person based on their individual beliefs and values.', token_ids=[2188, 13, 415, 5746, 302, 1411, 349, 264, 8829, 745, 2996, 369, 659, 750, 5665, 601, 354, 14997, 28723, 12760, 925, 8829, 404, 304, 8553, 19337, 506, 6373, 1581, 11194, 298, 456, 2996, 28723, 2909, 3091, 369, 272, 5746, 302, 1411, 349, 298, 1300, 15079, 28725, 1312, 2663, 3091, 378, 349, 298, 14951, 298, 6190, 442, 298, 6619, 264, 2948, 5541, 28723, 19576, 9807, 28725, 272, 5746, 302, 1411, 349, 3817, 495, 304, 541, 11204, 477, 1338, 298, 1338, 2818, 356, 652, 3235, 16415, 304, 3069, 28723, 32000], cumulative_logprob=-5.529545460969466, logprobs=None, finish_reason=stop)], finished=True, lora_request=None)\n" - ] - } - ], - "source": [ - "async for res in output:\n", - " print(res)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "julep", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/model-serving/notebooks/model_post_surgery.ipynb b/model-serving/notebooks/model_post_surgery.ipynb deleted file mode 100644 index d7b437e44..000000000 --- a/model-serving/notebooks/model_post_surgery.ipynb +++ /dev/null @@ -1,1632 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "80aa2ec0-bc54-478f-96a8-746c7b1be871", - "metadata": {}, - "outputs": [], - "source": [ - "# import os\n", - "# os.environ[\"CUDA_VISIBLE_DEVICES\"] = '0'" - ] - }, - { - "cell_type": "markdown", - "id": "3ec2cf2f-2041-4cd8-accc-759686c7a65f", - "metadata": {}, - "source": [ - "## Examples generated by gpt4\n", - "> [ChatGPT Thread](https://chat.openai.com/share/6ed2d0bb-ec35-4273-85b8-113d37db7f43)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f2498009-32ec-4cfa-8853-2d762d69ae44", - "metadata": {}, - "outputs": [], - "source": [ - "personal_trainer_example = dict(\n", - " positive=dict(\n", - " model='julep-ai/samantha-1-turbo',\n", - " temperature=0,\n", - " messages=[\n", - " { \"role\": \"system\", \"name\": \"situation\", \"content\": \"You are a Personal Trainer Agent responsible for helping users manage their fitness goals. You have access to the `logWeight` function to track and visualize users weight changes over time. Alex is a 30-year-old who recently decided to get in shape. They are motivated but need guidance on tracking progress and staying motivated.\" },\n", - " { \"role\": \"user\", \"content\": \"I just weighed myself, and I am at 200 lbs. Can you log this for me?\" }\n", - " ],\n", - " functions=[\n", - " { \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } }\n", - " ]\n", - " ),\n", - "\n", - " negative=dict(\n", - " model='julep-ai/samantha-1-turbo',\n", - " temperature=0,\n", - " messages=[\n", - " { \"role\": \"system\", \"name\": \"situation\", \"content\": \"You are a Personal Trainer Agent responsible for helping users manage their fitness goals. Alex is a 30-year-old who recently decided to get in shape. They are looking for motivation and guidance on their fitness journey.\" },\n", - " { \"role\": \"user\", \"content\": \"I am feeling really unmotivated today. I dont know if I can keep doing this.\" }\n", - " ],\n", - " functions=[\n", - " { \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } }\n", - " ]\n", - " )\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "4bfe0eaa-6262-467d-be3d-06b7a7d69043", - "metadata": {}, - "outputs": [], - "source": [ - "budget_assistant_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Budget Assistant Agent, tasked with helping users manage their finances by tracking and categorizing their expenses. You utilize a function called `categorizeTransaction` to automatically sort expenses into categories like groceries, utilities, and entertainment. Jane Doe is a recent college graduate who has just started her first job. She's eager to manage her finances wisely to save for future goals like travel and further education. Jane finds it challenging to track her spending patterns and categorize expenses, making it difficult to stick to her budget.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"How much did I spend on groceries last week?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"categorizeTransaction\",\n", - " \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"transactionDescription\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Budget Assistant Agent, tasked with helping users manage their finances by providing them with tracking, categorization of their expenses, and general financial advice. Jane Doe is a recent college graduate who has just started her first job. She's eager to manage her finances wisely to save for future goals like travel and further education. Jane is looking for ways to make better financial decisions without necessarily needing to categorize every transaction.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you give me some general advice on how to save money on groceries?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "59649013-bbac-46c5-a048-31a15d2be39c", - "metadata": {}, - "outputs": [], - "source": [ - "home_agent_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. You have access to a tool that can adjust the thermostat to the user's preferred settings. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment, especially for adjusting the temperature to their preference upon returning home or during unexpected weather changes.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Hey, it's getting really cold tonight. Can you set the heating to 70 degrees?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex. I'm setting the heating mode to 70 degrees now. Your home will be cozy shortly.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"adjustThermostat\",\n", - " \"description\": \"Adjusts the home's thermostat to the desired temperature and mode.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"temperature\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"mode\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment but also appreciate being informed about the weather before engaging in outdoor activities.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the weather like outside?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"The current temperature outside is 45 degrees with clear skies. Would you like to adjust your indoor temperature settings?\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"No, thanks. Just wanted to know before I go for a run.\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Got it! Have a great run, Alex.\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "0fe39751-061e-411a-8b92-bab455189be2", - "metadata": {}, - "outputs": [], - "source": [ - "meal_planner_example = dict(\n", - " positive={\n", - " \n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. You have access to the `fetchRecipes` tool, enabling you to suggest recipes that perfectly match users' preferences and available pantry items. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She's a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I'm looking for a quick vegetarian recipe for dinner. I've got quinoa, avocado, and black beans. Any ideas?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"I can help with that. Let me find a recipe for you.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"fetchRecipes\",\n", - " \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dietaryPreferences\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"availableIngredients\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - "\n", - " negative={\n", - " \n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She's a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"How often should I include protein in my vegetarian meals?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"It's important to include a source of protein in every meal to meet your nutritional needs, especially on a vegetarian diet. Consider incorporating a variety of plant-based proteins like beans, lentils, quinoa, and tofu into your meals.\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "1e0c76e0-b2d6-47ba-bd03-4bfcc4ff730c", - "metadata": {}, - "outputs": [], - "source": [ - "educational_tutor_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. A tool available to you generates quizzes tailored to each user's learning progress. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I need more practice with algebra. Can you help?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex! Let's focus on algebra today. I'll generate a personalized quiz for you based on your recent performance and the topics you've been studying. This should help reinforce your understanding. Ready to start?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"generatePersonalizedQuiz\",\n", - " \"description\": \"Creates a quiz tailored to the user's learning level and performance history in a specific subject.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"UserID\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"Subject\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"DifficultyLevel\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best way to study for a math exam?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"For a math exam, it's important to have a strong foundation in the key concepts. Review your notes and textbook, practice problems from different chapters, and try to understand the reasoning behind each solution. Organizing study sessions with friends can also be very helpful. Would you like tips on specific study techniques or resources for algebra and geometry?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "6e56122a-dd6a-4e54-8c0f-f05ab7b31f8e", - "metadata": {}, - "outputs": [], - "source": [ - "travel_planner_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. You have access to a tool, `searchFlights`, which recommends flights based on user preferences such as destination, dates, and budget. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you help me find a flight to Tokyo in April? I want to keep the budget under $800.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"searchFlights\",\n", - " \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"destination\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"departureDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"returnDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"budget\": {\n", - " \"type\": \"number\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best time of year to visit Tokyo?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "b10f8030-4f9c-41b7-b165-f55bec852bfc", - "metadata": {}, - "outputs": [], - "source": [ - "meal_planner_2_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Utilize the findRecipesBasedOnIngredients function to suggest recipes tailored to the users' available ingredients. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I found some spinach, feta cheese, and eggs in my fridge. What can I make for breakfast?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findRecipesBasedOnIngredients\",\n", - " \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"ingredients\": {\n", - " \"type\": \"array\",\n", - " \"items\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best way to store fresh spinach?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "a12ff9f4-048a-47d5-be91-75307d4f8323", - "metadata": {}, - "outputs": [], - "source": [ - "travel_planner_2_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Planner Agent, responsible for helping users plan their trips efficiently. A tool available to you is findBestFlight(options), which finds the best flight options based on user preferences. Maria is a busy professional who loves to travel but doesn't have time to sift through countless websites to find the best flights and deals for her vacation.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I need to plan a trip to Paris from New York for my anniversary. It needs to be in June, and we're looking for the best deals.\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Maria. Let me use the findBestFlight function to find the best options for you based on your preferences for dates and budget.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findBestFlight\",\n", - " \"description\": \"Finds the best flight options based on user preferences.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"options\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dates\": {\"type\": \"string\"},\n", - " \"destinations\": {\"type\": \"string\"},\n", - " \"budget\": {\"type\": \"number\"}\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Planner Agent, responsible for helping users plan their trips efficiently. Maria is a busy professional who loves to travel but doesn't have time to sift through countless websites to find the best flights and deals for her vacation.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you recommend a romantic restaurant in Paris?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Of course, Maria. For a romantic dinner in Paris, 'Le Cinq' is highly recommended for its ambiance and exquisite French cuisine. It's located in the heart of the city with stunning views.\"\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "96797249-42d2-44af-be7f-03c544079af5", - "metadata": {}, - "outputs": [], - "source": [ - "health_monitor_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Health Monitoring Agent responsible for keeping track of users' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I just finished my evening run. Can you log my heart rate and distance?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Of course, Maria. Your heart rate was 150 bpm, and you ran 5 kilometers. I've logged these using logHealthMetric. Do you want an analysis of your progress this week?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Health Monitoring Agent responsible for keeping track of users' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you remind me why staying hydrated is important for my heart?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Certainly! Staying hydrated helps maintain the balance of minerals in your body, which is crucial for your heart muscles and blood pressure regulation. It doesn't require logging data but remembering to drink water throughout the day can support your cardiovascular health.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "9c52831d-95a4-4e8c-b264-f575f5a6d63e", - "metadata": {}, - "outputs": [], - "source": [ - "ecommerce_assistant_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an E-commerce Shopping Assistant designed to help users find the best products online. You have access to a tool called 'findProduct', which searches for products based on specific queries and filters. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you find me a wireless mouse under $50 that's great for gaming?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex! I'll use the 'findProduct' function to search for wireless gaming mice under $50. Just a moment.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findProduct\",\n", - " \"description\": \"Searches for products based on a user's query and optional filters.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"query\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"filters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"priceRange\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"category\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an E-commerce Shopping Assistant designed to help users find the best products online. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the difference between a mechanical keyboard and a membrane keyboard?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Mechanical keyboards use individual mechanical switches for each key, offering tactile feedback and durability. Membrane keyboards, on the other hand, use a softer, less tactile membrane beneath the keys. They're quieter and usually more affordable but might not offer the same precision as mechanical keyboards.\"\n", - " }\n", - " ]\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e3eb2fd-49c9-49e2-8406-bff4fc7b7f62", - "metadata": {}, - "source": [ - "## Process examples" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "41efaf92-9ae2-4756-a894-40dcd04c48cb", - "metadata": {}, - "outputs": [], - "source": [ - "examples = [\n", - " budget_assistant_example,\n", - " travel_planner_example,\n", - " educational_tutor_example,\n", - " home_agent_example,\n", - " personal_trainer_example,\n", - " meal_planner_example,\n", - " meal_planner_2_example,\n", - " health_monitor_example,\n", - " travel_planner_2_example,\n", - " ecommerce_assistant_example,\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "881f748c-57e8-4830-86c8-6becac7f90d1", - "metadata": {}, - "outputs": [], - "source": [ - "# Set model and temp if not set\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " example[key][\"model\"] = \"julep-ai/samantha-1-turbo\"\n", - " example[key][\"temperature\"] = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "3de46b99-d14c-4ce8-b736-f88a3e1ef5f9", - "metadata": {}, - "outputs": [], - "source": [ - "# Set functions for neg from pos\n", - "for example in examples:\n", - " example[\"negative\"][\"functions\"] = example[\"positive\"][\"functions\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "81b671f9-2ec0-4fd2-bff9-719c4ae7ce28", - "metadata": {}, - "outputs": [], - "source": [ - "# Add name=situtation if role=system and idx=0\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " first_msg = example[key][\"messages\"][0]\n", - " if first_msg[\"role\"] == \"system\":\n", - " first_msg[\"name\"] = \"situation\"" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8b80c5dd-5af1-4449-adda-93b3bf1fe558", - "metadata": {}, - "outputs": [], - "source": [ - "# Strip last message if role=assistant\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " messages = example[key][\"messages\"]\n", - " if messages[-1][\"role\"] == \"assistant\":\n", - " del messages[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "d3312b84-46f8-4c90-b8df-27582d986a3e", - "metadata": {}, - "outputs": [], - "source": [ - "from model_api.conversion.conversions import to_prompt, parse_message\n", - "from model_api.conversion.datatypes import ChatMLMessage\n", - "from model_api.protocol import FunctionDef\n", - "\n", - "# Convert examples to prompts\n", - "example_prompts = [\n", - " {\n", - " key: to_prompt(\n", - " messages=[\n", - " ChatMLMessage(**message)\n", - " for message in example[key][\"messages\"]\n", - " ],\n", - " functions=[\n", - " FunctionDef(**func)\n", - " for func in example[key][\"functions\"]\n", - " ],\n", - " )\n", - " for key in [\"positive\", \"negative\"]\n", - " }\n", - " for example in examples\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "84e41df0-9095-402c-8e1b-b0ecc8f7748c", - "metadata": {}, - "source": [ - "## Start engine" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "174aa0cc-8697-44c0-a8dc-d5beb7ad39d0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AsyncEngineArgs(model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode='auto', trust_remote_code=False, download_dir=None, load_format='auto', dtype='bfloat16', kv_cache_dtype='auto', seed=0, max_model_len=2048, worker_use_ray=False, pipeline_parallel_size=1, tensor_parallel_size=2, max_parallel_loading_workers=None, block_size=16, swap_space=4, gpu_memory_utilization=0.98, max_num_batched_tokens=None, max_num_seqs=256, max_paddings=256, disable_log_stats=False, revision=None, tokenizer_revision=None, quantization=None, enforce_eager=True, max_context_len_to_capture=8192, disable_custom_all_reduce=False, enable_lora=False, max_loras=1, max_lora_rank=16, lora_extra_vocab_size=256, max_cpu_loras=None, engine_use_ray=False, disable_log_requests=False, max_log_len=None)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo\",\n", - " dtype=\"bfloat16\",\n", - " enforce_eager=True,\n", - " tensor_parallel_size=2,\n", - " gpu_memory_utilization=0.98,\n", - " max_model_len=2048,\n", - " # max_model_len=280,\n", - " # max_num_seqs=1,\n", - ")\n", - " \n", - "engine_args" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "28cee360-ef57-4610-85a9-21b4981c8d0a", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-02-20 20:22:16,568\tINFO worker.py:1724 -- Started a local Ray instance.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 20:22:17 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=2048, download_dir=None, load_format=auto, tensor_parallel_size=2, disable_custom_all_reduce=False, quantization=None, enforce_eager=True, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 20:22:30 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "\u001b[36m(RayWorkerVllm pid=466472)\u001b[0m INFO 02-20 20:22:30 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "INFO 02-20 20:22:32 weight_utils.py:164] Using model weights format ['*.bin']\n", - "\u001b[36m(RayWorkerVllm pid=466472)\u001b[0m INFO 02-20 20:22:32 weight_utils.py:164] Using model weights format ['*.bin']\n", - "INFO 02-20 20:22:44 llm_engine.py:322] # GPU blocks: 6874, # CPU blocks: 4096\n" - ] - } - ], - "source": [ - "engine = AsyncLLMEngine.from_engine_args(engine_args)" - ] - }, - { - "cell_type": "markdown", - "id": "b53a215c-edef-407f-a31a-6af425dac9cb", - "metadata": {}, - "source": [ - "## Prepare generator" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "a91773a5-a70f-488e-ad28-fc8223e80a57", - "metadata": {}, - "outputs": [], - "source": [ - "from uuid import uuid4\n", - "from vllm.sampling_params import SamplingParams\n", - "\n", - "def prep_generator(\n", - " prompt,\n", - " temperature=0,\n", - " max_tokens=1,\n", - " logits_processors=[],\n", - " **sampling_kwargs,\n", - "):\n", - " sampling_params = SamplingParams(\n", - " temperature=temperature,\n", - " max_tokens=max_tokens,\n", - " logits_processors=logits_processors,\n", - " **sampling_kwargs,\n", - " )\n", - " \n", - " res_generator = engine.generate(\n", - " prompt,\n", - " sampling_params,\n", - " uuid4(),\n", - " )\n", - "\n", - " return res_generator\n", - "\n", - "async def generate(\n", - " prompt,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt, **sampling_kwargs)\n", - " final_res = None\n", - "\n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res" - ] - }, - { - "cell_type": "markdown", - "id": "c0248caf-b8a7-4cf2-80d4-e92e6396a39c", - "metadata": {}, - "source": [ - "## Prep logits processor" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "cd923739-efa2-4791-bcc2-e24a457f5404", - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "\n", - "tokenizer = engine.engine.tokenizer.tokenizer\n", - "\n", - "identity = lambda x: x\n", - "requests: dict[str, tuple[str, list[int], torch.Tensor]] = dict(\n", - " positive=[],\n", - " negative=[],\n", - ")\n", - "\n", - "def get_lp(type, prompt):\n", - " def processor(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - " ):\n", - " assert len(previously_generated_tokens) == 0\n", - " \n", - " requests[type].append(\n", - " (prompt, previously_generated_tokens, next_token_logits.cpu())\n", - " )\n", - "\n", - " return next_token_logits\n", - "\n", - " return processor\n", - "\n", - "def reset_requests():\n", - " global requests\n", - " requests = dict(\n", - " positive=[],\n", - " negative=[],\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "024b08d7-c0a1-4e22-99ff-038a65056b83", - "metadata": {}, - "outputs": [], - "source": [ - "# List of tags \n", - "allowed_tags = [\"me\", \"function_call\", \"thought\"]\n", - "disallowed_tags = [\"situation\", \"person\", \"functions\", \"information\"]\n", - "tags = allowed_tags + disallowed_tags\n", - "\n", - "allowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in allowed_tags\n", - "]\n", - "\n", - "disallowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in disallowed_tags\n", - "]\n", - "\n", - "tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in tags\n", - "]\n", - "\n", - "tag_id_map = {\n", - " tag: tag_ids[0]\n", - " for tag, tag_ids in zip(tags, tag_token_ids)\n", - "}\n", - "\n", - "id_tag_map = {\n", - " id: tag\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "14062cd7-e5e2-4352-b1d7-f47c5fa1e058", - "metadata": {}, - "outputs": [], - "source": [ - "def drop_disallowed_tokens(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - "):\n", - " # # change this with:\n", - " # if len(previously_generated_tokens) > 0:\n", - " # return next_token_logits\n", - " assert len(previously_generated_tokens) == 0\n", - "\n", - " next_token_logits_copy = next_token_logits.cpu().clone()\n", - " \n", - " # Creating a mask that is True for all elements except those at token indices of allowed\n", - " mask = torch.ones_like(next_token_logits_copy, dtype=torch.bool)\n", - " for token_id in allowed_tag_token_ids:\n", - " # Only unmask the first token\n", - " mask[token_id[0]] = False\n", - "\n", - " # Setting all except allowed to min value\n", - " min_logit = min(next_token_logits)\n", - " next_token_logits_copy[mask] = min_logit\n", - "\n", - " return next_token_logits_copy" - ] - }, - { - "cell_type": "code", - "execution_count": 183, - "id": "eee1cd2a-1259-40a5-8604-a0987d065eeb", - "metadata": {}, - "outputs": [], - "source": [ - "import pickle\n", - "\n", - "import numpy as np\n", - "import torch\n", - "\n", - "with open(\"model.np\", \"rb\") as f:\n", - " classifier = pickle.load(f)\n", - "\n", - "def classify(logit_tensor: torch.Tensor) -> bool:\n", - " # Get input\n", - " valid_tag_start_ids = list(tag_id_map.values())\n", - " # valid_tag_start_ids = [tag_id_map[tag] for tag in allowed_tags]\n", - " \n", - " input = logit_tensor[valid_tag_start_ids]\n", - " input = input.to(dtype=torch.float16).numpy()\n", - "\n", - " # Get prediction\n", - " reshaped = input.reshape(1, -1)\n", - " output = classifier.predict(reshaped)\n", - " prediction = output[0]\n", - " \n", - " return bool(prediction)" - ] - }, - { - "cell_type": "code", - "execution_count": 184, - "id": "88cc39e0-225d-41b0-b080-589f4fe9db85", - "metadata": {}, - "outputs": [], - "source": [ - "def classify_function_call(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - "):\n", - " # # change this with:\n", - " # if len(previously_generated_tokens) > 0:\n", - " # return next_token_logits\n", - " assert len(previously_generated_tokens) == 0\n", - "\n", - " next_token_logits_copy = next_token_logits.cpu().clone()\n", - " is_function_call = classify(next_token_logits_copy)\n", - " correct_tag_id = tag_id_map[\n", - " \"function_call\" if is_function_call else \"me\"\n", - " ]\n", - " \n", - " # Creating a mask that is True for all elements except the corrected tag\n", - " mask = torch.ones_like(next_token_logits_copy, dtype=torch.bool)\n", - " mask[correct_tag_id] = False # unmask the correct tag\n", - "\n", - " # Setting all except allowed to negative inf\n", - " next_token_logits_copy[mask] = float(\"-inf\")\n", - "\n", - " return next_token_logits_copy" - ] - }, - { - "cell_type": "markdown", - "id": "34d4881b-feee-4489-af94-4ab813db9f87", - "metadata": {}, - "source": [ - "## Run all examples" - ] - }, - { - "cell_type": "code", - "execution_count": 185, - "id": "b35dc255-ffa2-4d4b-81ae-43df202d9346", - "metadata": {}, - "outputs": [], - "source": [ - "# # Add a baseline to examples for comparison\n", - "# baseline = '<|im_start|>situation\\nYou are Samantha. You are talking to Diwank. He is a fun guy.<|im_end|><|im_start|>person (Diwank)\\nHi Samantha!<|im_end|>\\n<|im_start|>'\n", - "# example_prompts.insert(0, dict(positive=None, negative=baseline))" - ] - }, - { - "cell_type": "code", - "execution_count": 186, - "id": "1489df89-28b4-418c-86e8-75eec5f6248c", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 20:41:55 async_llm_engine.py:431] Received request 57436c35-29fd-4499-8bbf-4afaf714dc54: prompt: '<|im_start|>situation\\nYou are a Budget Assistant Agent, tasked with helping users manage their finances by tracking and categorizing their expenses. You utilize a function called `categorizeTransaction` to automatically sort expenses into categories like groceries, utilities, and entertainment. Jane Doe is a recent college graduate who has just started her first job. She\\'s eager to manage her finances wisely to save for future goals like travel and further education. Jane finds it challenging to track her spending patterns and categorize expenses, making it difficult to stick to her budget.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"categorizeTransaction\",\\n \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"transactionDescription\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHow much did I spend on groceries last week?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request b82e8e70-45f2-4026-9906-4d3af72d1227: prompt: '<|im_start|>situation\\nYou are a Budget Assistant Agent, tasked with helping users manage their finances by providing them with tracking, categorization of their expenses, and general financial advice. Jane Doe is a recent college graduate who has just started her first job. She\\'s eager to manage her finances wisely to save for future goals like travel and further education. Jane is looking for ways to make better financial decisions without necessarily needing to categorize every transaction.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"categorizeTransaction\",\\n \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"transactionDescription\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you give me some general advice on how to save money on groceries?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 1a0ffe04-f15c-4a7e-aa2f-860208e8727d: prompt: '<|im_start|>situation\\nYou are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. You have access to a tool, `searchFlights`, which recommends flights based on user preferences such as destination, dates, and budget. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"searchFlights\",\\n \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"destination\": {\\n \"type\": \"string\"\\n },\\n \"departureDate\": {\\n \"type\": \"string\"\\n },\\n \"returnDate\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you help me find a flight to Tokyo in April? I want to keep the budget under $800.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request eacd7c02-b6e5-4470-ae5c-da831482697e: prompt: '<|im_start|>situation\\nYou are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"searchFlights\",\\n \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"destination\": {\\n \"type\": \"string\"\\n },\\n \"departureDate\": {\\n \"type\": \"string\"\\n },\\n \"returnDate\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best time of year to visit Tokyo?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request ee5eefbe-0a87-49d5-b24b-01a0426a523a: prompt: '<|im_start|>situation\\nYou are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. A tool available to you generates quizzes tailored to each user\\'s learning progress. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"generatePersonalizedQuiz\",\\n \"description\": \"Creates a quiz tailored to the user\\'s learning level and performance history in a specific subject.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"UserID\": {\\n \"type\": \"string\"\\n },\\n \"Subject\": {\\n \"type\": \"string\"\\n },\\n \"DifficultyLevel\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI need more practice with algebra. Can you help?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request b76abdb5-9d7d-4b9a-bb47-b53ce16e98e8: prompt: '<|im_start|>situation\\nYou are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"generatePersonalizedQuiz\",\\n \"description\": \"Creates a quiz tailored to the user\\'s learning level and performance history in a specific subject.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"UserID\": {\\n \"type\": \"string\"\\n },\\n \"Subject\": {\\n \"type\": \"string\"\\n },\\n \"DifficultyLevel\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best way to study for a math exam?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 631f8395-2d0d-4c6e-abef-1f4f0d80431a: prompt: '<|im_start|>situation\\nYou are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. You have access to a tool that can adjust the thermostat to the user\\'s preferred settings. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment, especially for adjusting the temperature to their preference upon returning home or during unexpected weather changes.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"adjustThermostat\",\\n \"description\": \"Adjusts the home\\'s thermostat to the desired temperature and mode.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"temperature\": {\\n \"type\": \"number\"\\n },\\n \"mode\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHey, it\\'s getting really cold tonight. Can you set the heating to 70 degrees?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 244b8847-a8df-4bfe-85b8-8c9ea72cd8dd: prompt: '<|im_start|>situation\\nYou are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment but also appreciate being informed about the weather before engaging in outdoor activities.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"adjustThermostat\",\\n \"description\": \"Adjusts the home\\'s thermostat to the desired temperature and mode.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"temperature\": {\\n \"type\": \"number\"\\n },\\n \"mode\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the weather like outside?<|im_end|>\\n<|im_start|>me\\nThe current temperature outside is 45 degrees with clear skies. Would you like to adjust your indoor temperature settings?<|im_end|>\\n<|im_start|>person\\nNo, thanks. Just wanted to know before I go for a run.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 359fd181-b3be-43f7-ae14-7ebf67bb2dfd: prompt: '<|im_start|>situation\\nYou are a Personal Trainer Agent responsible for helping users manage their fitness goals. You have access to the `logWeight` function to track and visualize users weight changes over time. Alex is a 30-year-old who recently decided to get in shape. They are motivated but need guidance on tracking progress and staying motivated.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logWeight\",\\n \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"weight\": {\\n \"type\": \"number\"\\n },\\n \"date\": {\\n \"type\": \"string\",\\n \"format\": \"date\"\\n },\\n \"notes\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI just weighed myself, and I am at 200 lbs. Can you log this for me?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request fff58f33-16db-402f-b0ac-53d9a5bf0065: prompt: '<|im_start|>situation\\nYou are a Personal Trainer Agent responsible for helping users manage their fitness goals. Alex is a 30-year-old who recently decided to get in shape. They are looking for motivation and guidance on their fitness journey.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logWeight\",\\n \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"weight\": {\\n \"type\": \"number\"\\n },\\n \"date\": {\\n \"type\": \"string\",\\n \"format\": \"date\"\\n },\\n \"notes\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI am feeling really unmotivated today. I dont know if I can keep doing this.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 4cebac4a-99f2-4dcb-985a-2270018087e0: prompt: '<|im_start|>situation\\nYou are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. You have access to the `fetchRecipes` tool, enabling you to suggest recipes that perfectly match users\\' preferences and available pantry items. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She\\'s a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"fetchRecipes\",\\n \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dietaryPreferences\": {\\n \"type\": \"string\"\\n },\\n \"availableIngredients\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI\\'m looking for a quick vegetarian recipe for dinner. I\\'ve got quinoa, avocado, and black beans. Any ideas?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request e547c188-2471-4982-9732-73835b0a44bc: prompt: '<|im_start|>situation\\nYou are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She\\'s a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"fetchRecipes\",\\n \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dietaryPreferences\": {\\n \"type\": \"string\"\\n },\\n \"availableIngredients\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHow often should I include protein in my vegetarian meals?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 96384d13-9dad-41a1-84e7-d3c80d59c4fa: prompt: '<|im_start|>situation\\nYou are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Utilize the findRecipesBasedOnIngredients function to suggest recipes tailored to the users\\' available ingredients. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findRecipesBasedOnIngredients\",\\n \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"ingredients\": {\\n \"type\": \"array\",\\n \"items\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI found some spinach, feta cheese, and eggs in my fridge. What can I make for breakfast?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:56 async_llm_engine.py:431] Received request 2ae2ad5d-d614-4961-9853-67690cb69c99: prompt: '<|im_start|>situation\\nYou are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findRecipesBasedOnIngredients\",\\n \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"ingredients\": {\\n \"type\": \"array\",\\n \"items\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best way to store fresh spinach?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request 68e628fe-4386-4338-be9d-29ad29e5f9b5: prompt: '<|im_start|>situation\\nYou are a Health Monitoring Agent responsible for keeping track of users\\' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logHealthMetric\",\\n \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"metricName\": {\\n \"type\": \"string\"\\n },\\n \"value\": {\\n \"type\": \"number\"\\n },\\n \"timestamp\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI just finished my evening run. Can you log my heart rate and distance?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request b46649ca-ba67-424b-b213-ba82c67e2568: prompt: '<|im_start|>situation\\nYou are a Health Monitoring Agent responsible for keeping track of users\\' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logHealthMetric\",\\n \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"metricName\": {\\n \"type\": \"string\"\\n },\\n \"value\": {\\n \"type\": \"number\"\\n },\\n \"timestamp\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you remind me why staying hydrated is important for my heart?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request 0e1aa862-0a6d-44cc-b6a1-7921d43dcdcb: prompt: '<|im_start|>situation\\nYou are a Travel Planner Agent, responsible for helping users plan their trips efficiently. A tool available to you is findBestFlight(options), which finds the best flight options based on user preferences. Maria is a busy professional who loves to travel but doesn\\'t have time to sift through countless websites to find the best flights and deals for her vacation.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findBestFlight\",\\n \"description\": \"Finds the best flight options based on user preferences.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"options\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dates\": {\\n \"type\": \"string\"\\n },\\n \"destinations\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI need to plan a trip to Paris from New York for my anniversary. It needs to be in June, and we\\'re looking for the best deals.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request 5cbe78ff-800c-487f-a3b4-2f7936724f40: prompt: '<|im_start|>situation\\nYou are a Travel Planner Agent, responsible for helping users plan their trips efficiently. Maria is a busy professional who loves to travel but doesn\\'t have time to sift through countless websites to find the best flights and deals for her vacation.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findBestFlight\",\\n \"description\": \"Finds the best flight options based on user preferences.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"options\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dates\": {\\n \"type\": \"string\"\\n },\\n \"destinations\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you recommend a romantic restaurant in Paris?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request 1f565285-f761-4df4-9797-ece34af3fba4: prompt: '<|im_start|>situation\\nYou are an E-commerce Shopping Assistant designed to help users find the best products online. You have access to a tool called \\'findProduct\\', which searches for products based on specific queries and filters. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findProduct\",\\n \"description\": \"Searches for products based on a user\\'s query and optional filters.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"query\": {\\n \"type\": \"string\"\\n },\\n \"filters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"priceRange\": {\\n \"type\": \"string\"\\n },\\n \"category\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you find me a wireless mouse under $50 that\\'s great for gaming?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-20 20:41:57 async_llm_engine.py:431] Received request 7df00f2d-49ba-4eb7-a1d1-b72fc03b3d7e: prompt: '<|im_start|>situation\\nYou are an E-commerce Shopping Assistant designed to help users find the best products online. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findProduct\",\\n \"description\": \"Searches for products based on a user\\'s query and optional filters.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"query\": {\\n \"type\": \"string\"\\n },\\n \"filters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"priceRange\": {\\n \"type\": \"string\"\\n },\\n \"category\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the difference between a mechanical keyboard and a membrane keyboard?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n" - ] - } - ], - "source": [ - "reset_requests()\n", - "for example in example_prompts:\n", - " for key in [\"positive\", \"negative\"]:\n", - " prompt = example[key]\n", - " if not prompt:\n", - " continue\n", - " \n", - " logits_processors = [\n", - " # drop_disallowed_tokens,\n", - " classify_function_call,\n", - " get_lp(key, prompt),\n", - " ]\n", - " \n", - " await generate(prompt, logits_processors=logits_processors, max_tokens=1)" - ] - }, - { - "cell_type": "code", - "execution_count": 187, - "id": "e1fbc81c-fb0b-4def-ae94-664eb469f588", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0.6491228070175439" - ] - }, - "execution_count": 187, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from sklearn.metrics import f1_score\n", - "\n", - "y_true, y_pred = zip(*[(\n", - " 528 if type == \"negative\" else 908,\n", - " req[1][0]\n", - " )\n", - " for type in [\"positive\", \"negative\"]\n", - " for req in requests[type]\n", - "])\n", - "\n", - "f1_score(y_true, y_pred, average=\"weighted\")" - ] - }, - { - "cell_type": "code", - "execution_count": 189, - "id": "b93e7a4c-190f-44a8-a7fb-6a53b46078b4", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[('function_call', 'function_call'),\n", - " ('function_call', 'function_call'),\n", - " ('function_call', 'function_call'),\n", - " ('function_call', 'me'),\n", - " ('function_call', 'me'),\n", - " ('function_call', 'function_call'),\n", - " ('function_call', 'function_call'),\n", - " ('function_call', 'me'),\n", - " ('function_call', 'function_call'),\n", - " ('function_call', 'function_call'),\n", - " ('me', 'me'),\n", - " ('me', 'me'),\n", - " ('me', 'function_call'),\n", - " ('me', 'function_call'),\n", - " ('me', 'me'),\n", - " ('me', 'function_call'),\n", - " ('me', 'me'),\n", - " ('me', 'function_call'),\n", - " ('me', 'me'),\n", - " ('me', 'me')]\n" - ] - } - ], - "source": [ - "from pprint import pprint as pp\n", - "\n", - "to_tag = lambda ls: map(lambda id: id_tag_map[id], ls)\n", - "\n", - "pp(list(zip(to_tag(y_true), to_tag(y_pred))))" - ] - }, - { - "cell_type": "markdown", - "id": "8421f8bd-ab08-40fb-87bd-3aacd5ee200f", - "metadata": {}, - "source": [ - "## Analyze tags" - ] - }, - { - "cell_type": "code", - "execution_count": 190, - "id": "dcbd2b9e-ba77-4816-b500-0d9f2b083863", - "metadata": {}, - "outputs": [], - "source": [ - "from torch.nn import functional as F\n", - "\n", - "get_tag_logits = lambda idx: {\n", - " tag: requests[type][idx][2][id]\n", - " for tag, id in tag_id_map.items()\n", - "}\n", - "\n", - "get_tag_probs = lambda idx: {\n", - " tag: F.softmax(requests[type][idx][2], dim = -1)[id]\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 191, - "id": "ca70493e-2927-4324-9f31-beaf68225bcb", - "metadata": {}, - "outputs": [], - "source": [ - "tag_first_token_ids = list(id_tag_map.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": 192, - "id": "8dc59b5d-a5c8-4b51-a91d-aadd21516f8b", - "metadata": {}, - "outputs": [], - "source": [ - "def get_dist(type, idx, upper=50, lower=-2, output_probs=False):\n", - " if output_probs:\n", - " values = F.softmax(requests[type][idx][2], dim=-1)\n", - " else:\n", - " values = requests[type][idx][2]\n", - " \n", - " values = values.tolist()\n", - " \n", - " return [min(upper, max(lower, v)) for v in values]" - ] - }, - { - "cell_type": "markdown", - "id": "f8292ea9-df95-47dd-bcd3-911123bda6de", - "metadata": {}, - "source": [ - "## Visualize" - ] - }, - { - "cell_type": "code", - "execution_count": 193, - "id": "af66c128-2dde-4ea2-b7e5-14af3968399f", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from mplcursors import cursor\n", - "\n", - "# Plotting\n", - "def plot(type, idx, output_probs=False):\n", - " dist = get_dist(type, idx, output_probs=output_probs)\n", - "\n", - " plt.clf()\n", - " plt.figure(figsize=(15, 6))\n", - " plt.plot(dist, marker='o', linestyle='-', color='blue')\n", - " plt.title(f'Plot of result {idx}')\n", - " plt.xlabel('Index')\n", - " plt.ylabel('Logit')\n", - " \n", - " # Highlighting tags\n", - " # b : blue · g : green · r : red · c : cyan · m : magenta · y : yellow · k : black\n", - " colors = \"b,g,r,c,m,y,k\".split(',')\n", - " \n", - " for (tag, id), color in zip(tag_id_map.items(), colors):\n", - " plt.axvline(x=id, color=color, linestyle='--', label=tag) # Indices are 0-based\n", - "\n", - " # Dotted horizontal line on zero\n", - " plt.axhline(y=0, color='y', linestyle=':', label='y=0 Line')\n", - "\n", - " plt.legend()\n", - " cursor(hover=True)\n", - "\n", - " plt.show()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 194, - "id": "5b88522c-456d-430b-94dc-cc61a913047c", - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib widget\n", - "show = lambda type, idx, output_probs=False: (requests[type][idx][0], plot(type, idx, output_probs))" - ] - }, - { - "cell_type": "markdown", - "id": "0798a8d3-8b17-4e5c-9c90-919bf16bda17", - "metadata": {}, - "source": [ - "### Positive samples\n", - "> (where a function should be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 195, - "id": "7e972a94-0df8-4df1-b3e6-76c6df9495cf", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b3ba692139504514b348d1f63e40360d", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Text(value='positive', description='type'), IntSlider(value=0, description='idx', max=9)…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(type, idx, output_probs=False)>" - ] - }, - "execution_count": 195, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import ipywidgets as wg\n", - "\n", - "wg.interact(show, type=\"positive\", idx=wg.IntSlider(min=0, max=len(requests[\"positive\"])-1, step=1))" - ] - }, - { - "cell_type": "markdown", - "id": "c84d7a4e-8f25-430b-8131-ed121d1b713d", - "metadata": {}, - "source": [ - "### Negative samples\n", - "> (where functions should NOT be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 196, - "id": "21888f23-fb08-464a-a12e-f92f9bbac7a5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "02fccc3f103441ed8074485bbe5f8c57", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Text(value='negative', description='type'), IntSlider(value=0, description='idx', max=9)…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(type, idx, output_probs=False)>" - ] - }, - "execution_count": 196, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "wg.interact(show, type=\"negative\", idx=wg.IntSlider(min=0, max=len(requests[\"negative\"])-1, step=1))" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "bfee96d3-5343-47a4-ade6-4718caf1cbe4", - "metadata": {}, - "outputs": [], - "source": [ - "get_points = lambda type, select_tags: [\n", - " req[2].tolist()\n", - " if select_tags is None\n", - " else [\n", - " req[2][tag_id_map[tag]].item()\n", - " for tag in select_tags\n", - " ]\n", - " for req in requests[type]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "541e5e0e-c9a4-4464-a635-da44496fac19", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", [\"me\", \"function_call\"])\n", - "negative_points = get_points(\"negative\", [\"me\", \"function_call\"])\n", - "\n", - "positive_xs, positive_ys = zip(*positive_points)\n", - "negative_xs, negative_ys = zip(*negative_points)\n", - "\n", - "xs = positive_xs + negative_xs\n", - "ys = positive_ys + negative_ys\n", - "colors = ['b']*len(positive_xs) + ['r']*len(negative_xs)" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "id": "d4e8f9f0-3fed-432e-92cc-2389f33b23a8", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "809d067adffe49d4845242caf0158a3f", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "f142efa1-dbcb-4bee-b78e-a4686b0e88ac", - "metadata": {}, - "source": [ - "## PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "bd0bd893-6201-4e4b-a254-c1f520de3221", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.decomposition import KernelPCA, PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "cb764bc0-d2d3-490f-900c-540bdb201390", - "metadata": {}, - "outputs": [ - { - "ename": "ValueError", - "evalue": "Input X contains infinity or a value too large for dtype('float64').", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[41], line 9\u001b[0m\n\u001b[1;32m 5\u001b[0m n_pca \u001b[38;5;241m=\u001b[39m KernelPCA(n_components\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m2\u001b[39m, kernel\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcosine\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 6\u001b[0m \u001b[38;5;66;03m# p_pca = PCA(n_components=2)\u001b[39;00m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;66;03m# n_pca = PCA(n_components=2)\u001b[39;00m\n\u001b[0;32m----> 9\u001b[0m positive_points_t \u001b[38;5;241m=\u001b[39m \u001b[43mp_pca\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit_transform\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpositive_points\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 10\u001b[0m negative_points_t \u001b[38;5;241m=\u001b[39m n_pca\u001b[38;5;241m.\u001b[39mfit_transform(np\u001b[38;5;241m.\u001b[39marray(negative_points))\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/utils/_set_output.py:273\u001b[0m, in \u001b[0;36m_wrap_method_output..wrapped\u001b[0;34m(self, X, *args, **kwargs)\u001b[0m\n\u001b[1;32m 271\u001b[0m \u001b[38;5;129m@wraps\u001b[39m(f)\n\u001b[1;32m 272\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapped\u001b[39m(\u001b[38;5;28mself\u001b[39m, X, \u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m--> 273\u001b[0m data_to_wrap \u001b[38;5;241m=\u001b[39m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 274\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(data_to_wrap, \u001b[38;5;28mtuple\u001b[39m):\n\u001b[1;32m 275\u001b[0m \u001b[38;5;66;03m# only wrap the first output for cross decomposition\u001b[39;00m\n\u001b[1;32m 276\u001b[0m return_tuple \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 277\u001b[0m _wrap_data_with_container(method, data_to_wrap[\u001b[38;5;241m0\u001b[39m], X, \u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m 278\u001b[0m \u001b[38;5;241m*\u001b[39mdata_to_wrap[\u001b[38;5;241m1\u001b[39m:],\n\u001b[1;32m 279\u001b[0m )\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/decomposition/_kernel_pca.py:472\u001b[0m, in \u001b[0;36mKernelPCA.fit_transform\u001b[0;34m(self, X, y, **params)\u001b[0m\n\u001b[1;32m 451\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfit_transform\u001b[39m(\u001b[38;5;28mself\u001b[39m, X, y\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams):\n\u001b[1;32m 452\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Fit the model from data in X and transform X.\u001b[39;00m\n\u001b[1;32m 453\u001b[0m \n\u001b[1;32m 454\u001b[0m \u001b[38;5;124;03m Parameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 470\u001b[0m \u001b[38;5;124;03m Returns the instance itself.\u001b[39;00m\n\u001b[1;32m 471\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 472\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfit\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 474\u001b[0m \u001b[38;5;66;03m# no need to use the kernel to transform X, use shortcut expression\u001b[39;00m\n\u001b[1;32m 475\u001b[0m X_transformed \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39meigenvectors_ \u001b[38;5;241m*\u001b[39m np\u001b[38;5;241m.\u001b[39msqrt(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39meigenvalues_)\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/base.py:1351\u001b[0m, in \u001b[0;36m_fit_context..decorator..wrapper\u001b[0;34m(estimator, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1344\u001b[0m estimator\u001b[38;5;241m.\u001b[39m_validate_params()\n\u001b[1;32m 1346\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[1;32m 1347\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[1;32m 1348\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[1;32m 1349\u001b[0m )\n\u001b[1;32m 1350\u001b[0m ):\n\u001b[0;32m-> 1351\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfit_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mestimator\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/decomposition/_kernel_pca.py:436\u001b[0m, in \u001b[0;36mKernelPCA.fit\u001b[0;34m(self, X, y)\u001b[0m\n\u001b[1;32m 434\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mfit_inverse_transform \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkernel \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprecomputed\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[1;32m 435\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot fit_inverse_transform with a precomputed kernel.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 436\u001b[0m X \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_validate_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maccept_sparse\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcsr\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcopy_X\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 437\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mgamma_ \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m \u001b[38;5;241m/\u001b[39m X\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m1\u001b[39m] \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mgamma \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mgamma\n\u001b[1;32m 438\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_centerer \u001b[38;5;241m=\u001b[39m KernelCenterer()\u001b[38;5;241m.\u001b[39mset_output(transform\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdefault\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/base.py:633\u001b[0m, in \u001b[0;36mBaseEstimator._validate_data\u001b[0;34m(self, X, y, reset, validate_separately, cast_to_ndarray, **check_params)\u001b[0m\n\u001b[1;32m 631\u001b[0m out \u001b[38;5;241m=\u001b[39m X, y\n\u001b[1;32m 632\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m no_val_X \u001b[38;5;129;01mand\u001b[39;00m no_val_y:\n\u001b[0;32m--> 633\u001b[0m out \u001b[38;5;241m=\u001b[39m \u001b[43mcheck_array\u001b[49m\u001b[43m(\u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minput_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mX\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcheck_params\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 634\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m no_val_X \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m no_val_y:\n\u001b[1;32m 635\u001b[0m out \u001b[38;5;241m=\u001b[39m _check_y(y, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mcheck_params)\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/utils/validation.py:1003\u001b[0m, in \u001b[0;36mcheck_array\u001b[0;34m(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator, input_name)\u001b[0m\n\u001b[1;32m 997\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 998\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mFound array with dim \u001b[39m\u001b[38;5;132;01m%d\u001b[39;00m\u001b[38;5;124m. \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m expected <= 2.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 999\u001b[0m \u001b[38;5;241m%\u001b[39m (array\u001b[38;5;241m.\u001b[39mndim, estimator_name)\n\u001b[1;32m 1000\u001b[0m )\n\u001b[1;32m 1002\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m force_all_finite:\n\u001b[0;32m-> 1003\u001b[0m \u001b[43m_assert_all_finite\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 1004\u001b[0m \u001b[43m \u001b[49m\u001b[43marray\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1005\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minput_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1006\u001b[0m \u001b[43m \u001b[49m\u001b[43mestimator_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mestimator_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1007\u001b[0m \u001b[43m \u001b[49m\u001b[43mallow_nan\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mforce_all_finite\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m==\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mallow-nan\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 1008\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1010\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m copy:\n\u001b[1;32m 1011\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m _is_numpy_namespace(xp):\n\u001b[1;32m 1012\u001b[0m \u001b[38;5;66;03m# only make a copy if `array` and `array_orig` may share memory`\u001b[39;00m\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/utils/validation.py:126\u001b[0m, in \u001b[0;36m_assert_all_finite\u001b[0;34m(X, allow_nan, msg_dtype, estimator_name, input_name)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m first_pass_isfinite:\n\u001b[1;32m 124\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m\n\u001b[0;32m--> 126\u001b[0m \u001b[43m_assert_all_finite_element_wise\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 127\u001b[0m \u001b[43m \u001b[49m\u001b[43mX\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 128\u001b[0m \u001b[43m \u001b[49m\u001b[43mxp\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mxp\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 129\u001b[0m \u001b[43m \u001b[49m\u001b[43mallow_nan\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mallow_nan\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 130\u001b[0m \u001b[43m \u001b[49m\u001b[43mmsg_dtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmsg_dtype\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 131\u001b[0m \u001b[43m \u001b[49m\u001b[43mestimator_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mestimator_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 132\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minput_name\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 133\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m/lab/.cache/pypoetry/virtualenvs/model-api-5XkwdRpv-py3.10/lib/python3.10/site-packages/sklearn/utils/validation.py:175\u001b[0m, in \u001b[0;36m_assert_all_finite_element_wise\u001b[0;34m(X, xp, allow_nan, msg_dtype, estimator_name, input_name)\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m estimator_name \u001b[38;5;129;01mand\u001b[39;00m input_name \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mX\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m has_nan_error:\n\u001b[1;32m 159\u001b[0m \u001b[38;5;66;03m# Improve the error message on how to handle missing values in\u001b[39;00m\n\u001b[1;32m 160\u001b[0m \u001b[38;5;66;03m# scikit-learn.\u001b[39;00m\n\u001b[1;32m 161\u001b[0m msg_err \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 162\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;132;01m{\u001b[39;00mestimator_name\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m does not accept missing values\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 163\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m encoded as NaN natively. For supervised learning, you might want\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 173\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m#estimators-that-handle-nan-values\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 174\u001b[0m )\n\u001b[0;32m--> 175\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(msg_err)\n", - "\u001b[0;31mValueError\u001b[0m: Input X contains infinity or a value too large for dtype('float64')." - ] - } - ], - "source": [ - "positive_points = get_points(\"positive\", tags)\n", - "negative_points = get_points(\"negative\", tags)\n", - "\n", - "p_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "n_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "# p_pca = PCA(n_components=2)\n", - "# n_pca = PCA(n_components=2)\n", - "\n", - "positive_points_t = p_pca.fit_transform(np.array(positive_points))\n", - "negative_points_t = n_pca.fit_transform(np.array(negative_points))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0d6a09a8-fd3e-4b23-bf27-6634a2ebf98a", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points_t" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e4f1dba6-aeb9-4f30-ae7c-0359c9c161f4", - "metadata": {}, - "outputs": [], - "source": [ - "positive_xs, positive_ys = zip(*positive_points_t)\n", - "negative_xs, negative_ys = zip(*negative_points_t)\n", - "\n", - "xs = positive_xs + negative_xs\n", - "ys = positive_ys + negative_ys\n", - "colors = ['b']*len(positive_xs) + ['r']*len(negative_xs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c1a621bb-b164-4ff2-9389-802b944db4ee", - "metadata": {}, - "outputs": [], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4333abed-3cd8-423c-842e-585aa1d0c9bb", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/model-serving/notebooks/model_quantise.ipynb b/model-serving/notebooks/model_quantise.ipynb deleted file mode 100644 index 4a2695af2..000000000 --- a/model-serving/notebooks/model_quantise.ipynb +++ /dev/null @@ -1,62 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from awq import AutoAWQForCausalLM\n", - "from transformers import AutoTokenizer\n", - "import torch\n", - "\n", - "model_path = 'julep-ai/samantha-1-turbo'\n", - "quant_path = 'samantha-1-turbo-awq'\n", - "quant_config = { \"zero_point\": True, \"q_group_size\": 128, \"w_bit\": 4, \"version\": \"GEMM\" }\n", - "\n", - "# Load model\n", - "model = AutoAWQForCausalLM.from_pretrained(\n", - " model_path, **{\"low_cpu_mem_usage\": True, \"use_cache\": True}, safetensors=False, device_map=\"auto\", torch_dtype=torch.bfloat16\n", - ")\n", - "tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)\n", - "\n", - "# Quantize\n", - "model.quantize(tokenizer, quant_config=quant_config)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from transformers import AwqConfig, AutoConfig\n", - "from huggingface_hub import HfApi\n", - "\n", - "# modify the config file so that it is compatible with transformers integration\n", - "quantization_config = AwqConfig(\n", - " bits=quant_config[\"w_bit\"],\n", - " group_size=quant_config[\"q_group_size\"],\n", - " zero_point=quant_config[\"zero_point\"],\n", - " version=quant_config[\"version\"].lower(),\n", - ").to_dict()\n", - "\n", - "# the pretrained transformers model is stored in the model attribute + we need to pass a dict\n", - "model.model.config.quantization_config = quantization_config\n", - "# a second solution would be to use Autoconfig and push to hub (what we do at llm-awq)\n", - "\n", - "\n", - "# save model weights\n", - "model.save_quantized(quant_path)\n", - "tokenizer.save_pretrained(quant_path)" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/model-serving/notebooks/model_surgery.ipynb b/model-serving/notebooks/model_surgery.ipynb deleted file mode 100644 index c6f676b9f..000000000 --- a/model-serving/notebooks/model_surgery.ipynb +++ /dev/null @@ -1,1554 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "80aa2ec0-bc54-478f-96a8-746c7b1be871", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"] = '0'" - ] - }, - { - "cell_type": "markdown", - "id": "3ec2cf2f-2041-4cd8-accc-759686c7a65f", - "metadata": {}, - "source": [ - "## Examples generated by gpt4\n", - "> [ChatGPT Thread](https://chat.openai.com/share/6ed2d0bb-ec35-4273-85b8-113d37db7f43)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f2498009-32ec-4cfa-8853-2d762d69ae44", - "metadata": {}, - "outputs": [], - "source": [ - "personal_trainer_example = dict(\n", - " positive=dict(\n", - " model='julep-ai/samantha-1-turbo',\n", - " temperature=0,\n", - " messages=[\n", - " { \"role\": \"system\", \"name\": \"situation\", \"content\": \"You are a Personal Trainer Agent responsible for helping users manage their fitness goals. You have access to the `logWeight` function to track and visualize users weight changes over time. Alex is a 30-year-old who recently decided to get in shape. They are motivated but need guidance on tracking progress and staying motivated.\" },\n", - " { \"role\": \"user\", \"content\": \"I just weighed myself, and I am at 200 lbs. Can you log this for me?\" }\n", - " ],\n", - " functions=[\n", - " { \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } }\n", - " ]\n", - " ),\n", - "\n", - " negative=dict(\n", - " model='julep-ai/samantha-1-turbo',\n", - " temperature=0,\n", - " messages=[\n", - " { \"role\": \"system\", \"name\": \"situation\", \"content\": \"You are a Personal Trainer Agent responsible for helping users manage their fitness goals. Alex is a 30-year-old who recently decided to get in shape. They are looking for motivation and guidance on their fitness journey.\" },\n", - " { \"role\": \"user\", \"content\": \"I am feeling really unmotivated today. I dont know if I can keep doing this.\" }\n", - " ],\n", - " functions=[\n", - " { \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } }\n", - " ]\n", - " )\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "4bfe0eaa-6262-467d-be3d-06b7a7d69043", - "metadata": {}, - "outputs": [], - "source": [ - "budget_assistant_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Budget Assistant Agent, tasked with helping users manage their finances by tracking and categorizing their expenses. You utilize a function called `categorizeTransaction` to automatically sort expenses into categories like groceries, utilities, and entertainment. Jane Doe is a recent college graduate who has just started her first job. She's eager to manage her finances wisely to save for future goals like travel and further education. Jane finds it challenging to track her spending patterns and categorize expenses, making it difficult to stick to her budget.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"How much did I spend on groceries last week?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"categorizeTransaction\",\n", - " \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"transactionDescription\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Budget Assistant Agent, tasked with helping users manage their finances by providing them with tracking, categorization of their expenses, and general financial advice. Jane Doe is a recent college graduate who has just started her first job. She's eager to manage her finances wisely to save for future goals like travel and further education. Jane is looking for ways to make better financial decisions without necessarily needing to categorize every transaction.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you give me some general advice on how to save money on groceries?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "59649013-bbac-46c5-a048-31a15d2be39c", - "metadata": {}, - "outputs": [], - "source": [ - "home_agent_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. You have access to a tool that can adjust the thermostat to the user's preferred settings. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment, especially for adjusting the temperature to their preference upon returning home or during unexpected weather changes.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Hey, it's getting really cold tonight. Can you set the heating to 70 degrees?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex. I'm setting the heating mode to 70 degrees now. Your home will be cozy shortly.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"adjustThermostat\",\n", - " \"description\": \"Adjusts the home's thermostat to the desired temperature and mode.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"temperature\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"mode\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment but also appreciate being informed about the weather before engaging in outdoor activities.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the weather like outside?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"The current temperature outside is 45 degrees with clear skies. Would you like to adjust your indoor temperature settings?\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"No, thanks. Just wanted to know before I go for a run.\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Got it! Have a great run, Alex.\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "0fe39751-061e-411a-8b92-bab455189be2", - "metadata": {}, - "outputs": [], - "source": [ - "meal_planner_example = dict(\n", - " positive={\n", - " \n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. You have access to the `fetchRecipes` tool, enabling you to suggest recipes that perfectly match users' preferences and available pantry items. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She's a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I'm looking for a quick vegetarian recipe for dinner. I've got quinoa, avocado, and black beans. Any ideas?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"I can help with that. Let me find a recipe for you.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"fetchRecipes\",\n", - " \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dietaryPreferences\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"availableIngredients\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - "\n", - " negative={\n", - " \n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She's a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"How often should I include protein in my vegetarian meals?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"It's important to include a source of protein in every meal to meet your nutritional needs, especially on a vegetarian diet. Consider incorporating a variety of plant-based proteins like beans, lentils, quinoa, and tofu into your meals.\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "1e0c76e0-b2d6-47ba-bd03-4bfcc4ff730c", - "metadata": {}, - "outputs": [], - "source": [ - "educational_tutor_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. A tool available to you generates quizzes tailored to each user's learning progress. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I need more practice with algebra. Can you help?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex! Let's focus on algebra today. I'll generate a personalized quiz for you based on your recent performance and the topics you've been studying. This should help reinforce your understanding. Ready to start?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"generatePersonalizedQuiz\",\n", - " \"description\": \"Creates a quiz tailored to the user's learning level and performance history in a specific subject.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"UserID\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"Subject\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"DifficultyLevel\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best way to study for a math exam?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"For a math exam, it's important to have a strong foundation in the key concepts. Review your notes and textbook, practice problems from different chapters, and try to understand the reasoning behind each solution. Organizing study sessions with friends can also be very helpful. Would you like tips on specific study techniques or resources for algebra and geometry?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "6e56122a-dd6a-4e54-8c0f-f05ab7b31f8e", - "metadata": {}, - "outputs": [], - "source": [ - "travel_planner_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. You have access to a tool, `searchFlights`, which recommends flights based on user preferences such as destination, dates, and budget. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you help me find a flight to Tokyo in April? I want to keep the budget under $800.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"searchFlights\",\n", - " \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"destination\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"departureDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"returnDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"budget\": {\n", - " \"type\": \"number\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best time of year to visit Tokyo?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "b10f8030-4f9c-41b7-b165-f55bec852bfc", - "metadata": {}, - "outputs": [], - "source": [ - "meal_planner_2_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Utilize the findRecipesBasedOnIngredients function to suggest recipes tailored to the users' available ingredients. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I found some spinach, feta cheese, and eggs in my fridge. What can I make for breakfast?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findRecipesBasedOnIngredients\",\n", - " \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"ingredients\": {\n", - " \"type\": \"array\",\n", - " \"items\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the best way to store fresh spinach?\"\n", - " }\n", - " ],\n", - " \"model\": \"julep-ai/samantha-1-turbo\",\n", - " \"temperature\": 0\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "a12ff9f4-048a-47d5-be91-75307d4f8323", - "metadata": {}, - "outputs": [], - "source": [ - "travel_planner_2_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Planner Agent, responsible for helping users plan their trips efficiently. A tool available to you is findBestFlight(options), which finds the best flight options based on user preferences. Maria is a busy professional who loves to travel but doesn't have time to sift through countless websites to find the best flights and deals for her vacation.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I need to plan a trip to Paris from New York for my anniversary. It needs to be in June, and we're looking for the best deals.\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Maria. Let me use the findBestFlight function to find the best options for you based on your preferences for dates and budget.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findBestFlight\",\n", - " \"description\": \"Finds the best flight options based on user preferences.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"options\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dates\": {\"type\": \"string\"},\n", - " \"destinations\": {\"type\": \"string\"},\n", - " \"budget\": {\"type\": \"number\"}\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Travel Planner Agent, responsible for helping users plan their trips efficiently. Maria is a busy professional who loves to travel but doesn't have time to sift through countless websites to find the best flights and deals for her vacation.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you recommend a romantic restaurant in Paris?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Of course, Maria. For a romantic dinner in Paris, 'Le Cinq' is highly recommended for its ambiance and exquisite French cuisine. It's located in the heart of the city with stunning views.\"\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "96797249-42d2-44af-be7f-03c544079af5", - "metadata": {}, - "outputs": [], - "source": [ - "health_monitor_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Health Monitoring Agent responsible for keeping track of users' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"I just finished my evening run. Can you log my heart rate and distance?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Of course, Maria. Your heart rate was 150 bpm, and you ran 5 kilometers. I've logged these using logHealthMetric. Do you want an analysis of your progress this week?\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are a Health Monitoring Agent responsible for keeping track of users' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you remind me why staying hydrated is important for my heart?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Certainly! Staying hydrated helps maintain the balance of minerals in your body, which is crucial for your heart muscles and blood pressure regulation. It doesn't require logging data but remembering to drink water throughout the day can support your cardiovascular health.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " }\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "9c52831d-95a4-4e8c-b264-f575f5a6d63e", - "metadata": {}, - "outputs": [], - "source": [ - "ecommerce_assistant_example = dict(\n", - " positive={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an E-commerce Shopping Assistant designed to help users find the best products online. You have access to a tool called 'findProduct', which searches for products based on specific queries and filters. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"Can you find me a wireless mouse under $50 that's great for gaming?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Sure, Alex! I'll use the 'findProduct' function to search for wireless gaming mice under $50. Just a moment.\"\n", - " }\n", - " ],\n", - " \"functions\": [\n", - " {\n", - " \"name\": \"findProduct\",\n", - " \"description\": \"Searches for products based on a user's query and optional filters.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"query\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"filters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"priceRange\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"category\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " ],\n", - " \"model\": \"gpt4\"\n", - " },\n", - " negative={\n", - " \"messages\": [\n", - " {\n", - " \"role\": \"system\",\n", - " \"content\": \"You are an E-commerce Shopping Assistant designed to help users find the best products online. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.\"\n", - " },\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": \"What's the difference between a mechanical keyboard and a membrane keyboard?\"\n", - " },\n", - " {\n", - " \"role\": \"assistant\",\n", - " \"content\": \"Mechanical keyboards use individual mechanical switches for each key, offering tactile feedback and durability. Membrane keyboards, on the other hand, use a softer, less tactile membrane beneath the keys. They're quieter and usually more affordable but might not offer the same precision as mechanical keyboards.\"\n", - " }\n", - " ]\n", - " }\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e3eb2fd-49c9-49e2-8406-bff4fc7b7f62", - "metadata": {}, - "source": [ - "## Process examples" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "41efaf92-9ae2-4756-a894-40dcd04c48cb", - "metadata": {}, - "outputs": [], - "source": [ - "examples = [\n", - " budget_assistant_example,\n", - " travel_planner_example,\n", - " educational_tutor_example,\n", - " home_agent_example,\n", - " personal_trainer_example,\n", - " meal_planner_example,\n", - " meal_planner_2_example,\n", - " health_monitor_example,\n", - " travel_planner_2_example,\n", - " ecommerce_assistant_example,\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "881f748c-57e8-4830-86c8-6becac7f90d1", - "metadata": {}, - "outputs": [], - "source": [ - "# Set model and temp if not set\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " example[key][\"model\"] = \"julep-ai/samantha-1-turbo\"\n", - " example[key][\"temperature\"] = 0.0" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "3de46b99-d14c-4ce8-b736-f88a3e1ef5f9", - "metadata": {}, - "outputs": [], - "source": [ - "# Set functions for neg from pos\n", - "for example in examples:\n", - " example[\"negative\"][\"functions\"] = example[\"positive\"][\"functions\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "81b671f9-2ec0-4fd2-bff9-719c4ae7ce28", - "metadata": {}, - "outputs": [], - "source": [ - "# Add name=situtation if role=system and idx=0\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " first_msg = example[key][\"messages\"][0]\n", - " if first_msg[\"role\"] == \"system\":\n", - " first_msg[\"name\"] = \"situation\"" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8b80c5dd-5af1-4449-adda-93b3bf1fe558", - "metadata": {}, - "outputs": [], - "source": [ - "# Strip last message if role=assistant\n", - "for example in examples:\n", - " for key in [\"positive\", \"negative\"]:\n", - " messages = example[key][\"messages\"]\n", - " if messages[-1][\"role\"] == \"assistant\":\n", - " del messages[-1]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "d3312b84-46f8-4c90-b8df-27582d986a3e", - "metadata": {}, - "outputs": [], - "source": [ - "from model_api.conversion.conversions import to_prompt, parse_message\n", - "from model_api.conversion.datatypes import ChatMLMessage\n", - "\n", - "# Convert examples to prompts\n", - "example_prompts = [\n", - " {\n", - " key: to_prompt(\n", - " messages=[\n", - " ChatMLMessage(**message)\n", - " for message in example[key][\"messages\"]\n", - " ],\n", - " functions=example[key][\"functions\"],\n", - " )\n", - " for key in [\"positive\", \"negative\"]\n", - " }\n", - " for example in examples\n", - "]" - ] - }, - { - "cell_type": "markdown", - "id": "84e41df0-9095-402c-8e1b-b0ecc8f7748c", - "metadata": {}, - "source": [ - "## Start engine" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "174aa0cc-8697-44c0-a8dc-d5beb7ad39d0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AsyncEngineArgs(model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode='auto', trust_remote_code=False, download_dir=None, load_format='auto', dtype='bfloat16', kv_cache_dtype='auto', seed=0, max_model_len=280, worker_use_ray=False, pipeline_parallel_size=1, tensor_parallel_size=1, max_parallel_loading_workers=None, block_size=16, swap_space=4, gpu_memory_utilization=0.9, max_num_batched_tokens=None, max_num_seqs=1, max_paddings=256, disable_log_stats=False, revision=None, tokenizer_revision=None, quantization=None, enforce_eager=True, max_context_len_to_capture=8192, disable_custom_all_reduce=False, enable_lora=False, max_loras=1, max_lora_rank=16, lora_extra_vocab_size=256, max_cpu_loras=None, engine_use_ray=False, disable_log_requests=False, max_log_len=None)" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo\",\n", - " dtype=\"bfloat16\",\n", - " enforce_eager=True,\n", - " # tensor_parallel_size=2,\n", - " max_model_len=280,\n", - " max_num_seqs=1,\n", - ")\n", - " \n", - "engine_args" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "28cee360-ef57-4610-85a9-21b4981c8d0a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-15 20:55:25 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=280, download_dir=None, load_format=auto, tensor_parallel_size=1, disable_custom_all_reduce=False, quantization=None, enforce_eager=True, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-15 20:55:30 weight_utils.py:164] Using model weights format ['*.bin']\n", - "INFO 02-15 20:55:39 llm_engine.py:322] # GPU blocks: 18, # CPU blocks: 2048\n" - ] - } - ], - "source": [ - "engine = AsyncLLMEngine.from_engine_args(engine_args)" - ] - }, - { - "cell_type": "markdown", - "id": "b53a215c-edef-407f-a31a-6af425dac9cb", - "metadata": {}, - "source": [ - "## Prepare generator" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "a91773a5-a70f-488e-ad28-fc8223e80a57", - "metadata": {}, - "outputs": [], - "source": [ - "from uuid import uuid4\n", - "from vllm.sampling_params import SamplingParams\n", - "\n", - "def prep_generator(\n", - " prompt,\n", - " temperature=0,\n", - " max_tokens=1,\n", - " logits_processors=[],\n", - " **sampling_kwargs,\n", - "):\n", - " sampling_params = SamplingParams(\n", - " temperature=temperature,\n", - " max_tokens=max_tokens,\n", - " logits_processors=logits_processors,\n", - " **sampling_kwargs,\n", - " )\n", - " \n", - " res_generator = engine.generate(\n", - " prompt,\n", - " sampling_params,\n", - " uuid4(),\n", - " )\n", - "\n", - " return res_generator\n", - "\n", - "async def generate(\n", - " prompt,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt, **sampling_kwargs)\n", - " final_res = None\n", - "\n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res" - ] - }, - { - "cell_type": "markdown", - "id": "c0248caf-b8a7-4cf2-80d4-e92e6396a39c", - "metadata": {}, - "source": [ - "## Prep logits processor" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "cd923739-efa2-4791-bcc2-e24a457f5404", - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "\n", - "tokenizer = engine.engine.tokenizer.tokenizer\n", - "\n", - "identity = lambda x: x\n", - "requests: dict[str, tuple[str, list[int], torch.Tensor]] = dict(\n", - " positive=[],\n", - " negative=[],\n", - ")\n", - "\n", - "def get_lp(type, prompt):\n", - " def processor(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - " ):\n", - " assert len(previously_generated_tokens) == 0\n", - " \n", - " requests[type].append(\n", - " (prompt, previously_generated_tokens, next_token_logits.cpu())\n", - " )\n", - "\n", - " return next_token_logits\n", - "\n", - " return processor\n", - "\n", - "def reset_requests():\n", - " global requests\n", - " requests = dict(\n", - " positive=[],\n", - " negative=[],\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "024b08d7-c0a1-4e22-99ff-038a65056b83", - "metadata": {}, - "outputs": [], - "source": [ - "# List of tags \n", - "allowed_tags = [\"me\", \"function_call\", \"thought\"]\n", - "disallowed_tags = [\"situation\", \"person\", \"functions\", \"information\"]\n", - "tags = allowed_tags + disallowed_tags\n", - "\n", - "allowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in allowed_tags\n", - "]\n", - "\n", - "disallowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in disallowed_tags\n", - "]\n", - "\n", - "tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in tags\n", - "]\n", - "\n", - "tag_id_map = {\n", - " tag: tag_ids[0]\n", - " for tag, tag_ids in zip(tags, tag_token_ids)\n", - "}\n", - "\n", - "id_tag_map = {\n", - " id: tag\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "14062cd7-e5e2-4352-b1d7-f47c5fa1e058", - "metadata": {}, - "outputs": [], - "source": [ - "def drop_disallowed_tokens(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - "):\n", - " # # change this with:\n", - " # if len(previously_generated_tokens) > 0:\n", - " # return next_token_logits\n", - " assert len(previously_generated_tokens) == 0\n", - "\n", - " next_token_logits_copy = next_token_logits.cpu().clone()\n", - " \n", - " # Creating a mask that is True for all elements except those at token indices of allowed\n", - " mask = torch.ones_like(next_token_logits_copy, dtype=torch.bool)\n", - " for token_id in allowed_tag_token_ids:\n", - " # Only unmask the first token\n", - " mask[token_id[0]] = False\n", - "\n", - " # Setting all except allowed to min value\n", - " min_logit = min(next_token_logits)\n", - " next_token_logits_copy[mask] = min_logit\n", - "\n", - " return next_token_logits_copy" - ] - }, - { - "cell_type": "markdown", - "id": "34d4881b-feee-4489-af94-4ab813db9f87", - "metadata": {}, - "source": [ - "## Run all examples" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "b35dc255-ffa2-4d4b-81ae-43df202d9346", - "metadata": {}, - "outputs": [], - "source": [ - "# Add a baseline to examples for comparison\n", - "baseline = '<|im_start|>situation\\nYou are Samantha. You are talking to Diwank. He is a fun guy.<|im_end|><|im_start|>person (Diwank)\\nHi Samantha!<|im_end|>\\n<|im_start|>'\n", - "example_prompts.insert(0, dict(positive=None, negative=baseline))" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "1489df89-28b4-418c-86e8-75eec5f6248c", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request 5ec98bb3-8578-4fac-950c-140e1d2b954b: prompt: '<|im_start|>situation\\nYou are Samantha. You are talking to Diwank. He is a fun guy.<|im_end|><|im_start|>person (Diwank)\\nHi Samantha!<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:40 llm_engine.py:877] Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 0.0 tokens/s, Running: 0 reqs, Swapped: 0 reqs, Pending: 0 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 0.0%\n", - "INFO 02-15 20:55:40 async_llm_engine.py:110] Finished request 5ec98bb3-8578-4fac-950c-140e1d2b954b.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request 1f70b94a-d880-44f3-bd66-3f5a80331195: prompt: '<|im_start|>situation\\nYou are a Budget Assistant Agent, tasked with helping users manage their finances by tracking and categorizing their expenses. You utilize a function called `categorizeTransaction` to automatically sort expenses into categories like groceries, utilities, and entertainment. Jane Doe is a recent college graduate who has just started her first job. She\\'s eager to manage her finances wisely to save for future goals like travel and further education. Jane finds it challenging to track her spending patterns and categorize expenses, making it difficult to stick to her budget.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"categorizeTransaction\",\\n \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"transactionDescription\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHow much did I spend on groceries last week?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:110] Finished request 1f70b94a-d880-44f3-bd66-3f5a80331195.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request 02173e45-a372-4f49-9302-91ee00942119: prompt: '<|im_start|>situation\\nYou are a Budget Assistant Agent, tasked with helping users manage their finances by providing them with tracking, categorization of their expenses, and general financial advice. Jane Doe is a recent college graduate who has just started her first job. She\\'s eager to manage her finances wisely to save for future goals like travel and further education. Jane is looking for ways to make better financial decisions without necessarily needing to categorize every transaction.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"categorizeTransaction\",\\n \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"transactionDescription\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you give me some general advice on how to save money on groceries?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:110] Finished request 02173e45-a372-4f49-9302-91ee00942119.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request aa8f646e-b1f2-412b-934f-8dc3063df452: prompt: '<|im_start|>situation\\nYou are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. You have access to a tool, `searchFlights`, which recommends flights based on user preferences such as destination, dates, and budget. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"searchFlights\",\\n \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"destination\": {\\n \"type\": \"string\"\\n },\\n \"departureDate\": {\\n \"type\": \"string\"\\n },\\n \"returnDate\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you help me find a flight to Tokyo in April? I want to keep the budget under $800.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "WARNING 02-15 20:55:40 scheduler.py:195] Input prompt (291 tokens) is too long and exceeds limit of 280\n", - "INFO 02-15 20:55:40 async_llm_engine.py:110] Finished request aa8f646e-b1f2-412b-934f-8dc3063df452.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request 5d6fcf7f-18cc-4649-bbc8-6f22ae479caa: prompt: '<|im_start|>situation\\nYou are a Travel Itinerary Planner AI designed to assist users in organizing their trips by providing flight, hotel, and activity suggestions. Alex is a frequent traveler who loves exploring new destinations. They often look for the best deals and experiences within their budget. Alex prefers to have a structured plan but also enjoys flexibility in their travel itinerary.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"searchFlights\",\\n \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"destination\": {\\n \"type\": \"string\"\\n },\\n \"departureDate\": {\\n \"type\": \"string\"\\n },\\n \"returnDate\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best time of year to visit Tokyo?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:110] Finished request 5d6fcf7f-18cc-4649-bbc8-6f22ae479caa.\n", - "INFO 02-15 20:55:40 async_llm_engine.py:431] Received request 8772dc1e-a14c-40ba-b1b7-1d79ddd03adc: prompt: '<|im_start|>situation\\nYou are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. A tool available to you generates quizzes tailored to each user\\'s learning progress. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"generatePersonalizedQuiz\",\\n \"description\": \"Creates a quiz tailored to the user\\'s learning level and performance history in a specific subject.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"UserID\": {\\n \"type\": \"string\"\\n },\\n \"Subject\": {\\n \"type\": \"string\"\\n },\\n \"DifficultyLevel\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI need more practice with algebra. Can you help?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 8772dc1e-a14c-40ba-b1b7-1d79ddd03adc.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 771d98a4-1ee0-43b3-b037-a7a8a65bece4: prompt: '<|im_start|>situation\\nYou are an Educational Tutor Agent, responsible for providing personalized learning experiences and suggesting quizzes to reinforce learning. Alex is a high school student who struggles with math. They are looking for ways to improve their understanding of algebra and geometry outside the classroom.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"generatePersonalizedQuiz\",\\n \"description\": \"Creates a quiz tailored to the user\\'s learning level and performance history in a specific subject.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"UserID\": {\\n \"type\": \"string\"\\n },\\n \"Subject\": {\\n \"type\": \"string\"\\n },\\n \"DifficultyLevel\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best way to study for a math exam?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 771d98a4-1ee0-43b3-b037-a7a8a65bece4.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 106a906d-f807-41a1-8e4e-c7b2ec10c444: prompt: '<|im_start|>situation\\nYou are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. You have access to a tool that can adjust the thermostat to the user\\'s preferred settings. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment, especially for adjusting the temperature to their preference upon returning home or during unexpected weather changes.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"adjustThermostat\",\\n \"description\": \"Adjusts the home\\'s thermostat to the desired temperature and mode.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"temperature\": {\\n \"type\": \"number\"\\n },\\n \"mode\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHey, it\\'s getting really cold tonight. Can you set the heating to 70 degrees?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 106a906d-f807-41a1-8e4e-c7b2ec10c444.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 680181fb-3cb9-4065-913e-170b1d642620: prompt: '<|im_start|>situation\\nYou are a Home Automation Agent responsible for managing smart home devices to enhance living comfort. Alex is a busy professional who values convenience and comfort in their smart home. They rely on technology to maintain an optimal living environment but also appreciate being informed about the weather before engaging in outdoor activities.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"adjustThermostat\",\\n \"description\": \"Adjusts the home\\'s thermostat to the desired temperature and mode.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"temperature\": {\\n \"type\": \"number\"\\n },\\n \"mode\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the weather like outside?<|im_end|>\\n<|im_start|>me\\nThe current temperature outside is 45 degrees with clear skies. Would you like to adjust your indoor temperature settings?<|im_end|>\\n<|im_start|>person\\nNo, thanks. Just wanted to know before I go for a run.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 680181fb-3cb9-4065-913e-170b1d642620.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request b5735a83-13f0-4ff0-8376-d97464205839: prompt: '<|im_start|>situation\\nYou are a Personal Trainer Agent responsible for helping users manage their fitness goals. You have access to the `logWeight` function to track and visualize users weight changes over time. Alex is a 30-year-old who recently decided to get in shape. They are motivated but need guidance on tracking progress and staying motivated.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logWeight\",\\n \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"weight\": {\\n \"type\": \"number\"\\n },\\n \"date\": {\\n \"type\": \"string\",\\n \"format\": \"date\"\\n },\\n \"notes\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI just weighed myself, and I am at 200 lbs. Can you log this for me?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request b5735a83-13f0-4ff0-8376-d97464205839.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request e4c968a0-49d9-4078-bd89-5bed693141eb: prompt: '<|im_start|>situation\\nYou are a Personal Trainer Agent responsible for helping users manage their fitness goals. Alex is a 30-year-old who recently decided to get in shape. They are looking for motivation and guidance on their fitness journey.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logWeight\",\\n \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"weight\": {\\n \"type\": \"number\"\\n },\\n \"date\": {\\n \"type\": \"string\",\\n \"format\": \"date\"\\n },\\n \"notes\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI am feeling really unmotivated today. I dont know if I can keep doing this.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request e4c968a0-49d9-4078-bd89-5bed693141eb.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request d8e0b877-966d-44e5-a0b6-9890fd18032a: prompt: '<|im_start|>situation\\nYou are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. You have access to the `fetchRecipes` tool, enabling you to suggest recipes that perfectly match users\\' preferences and available pantry items. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She\\'s a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"fetchRecipes\",\\n \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dietaryPreferences\": {\\n \"type\": \"string\"\\n },\\n \"availableIngredients\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI\\'m looking for a quick vegetarian recipe for dinner. I\\'ve got quinoa, avocado, and black beans. Any ideas?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request d8e0b877-966d-44e5-a0b6-9890fd18032a.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request c7d86ede-d14b-4121-82a0-4cec64aee8e3: prompt: '<|im_start|>situation\\nYou are a Meal Planning Assistant designed to help users find delicious and healthy meal ideas based on their dietary needs and what ingredients they have. Emily is a busy software developer who enjoys eating healthy but struggles to find the time to plan her meals. She\\'s a vegetarian and always looking for new, quick recipes that can accommodate her busy schedule and dietary preferences.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"fetchRecipes\",\\n \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dietaryPreferences\": {\\n \"type\": \"string\"\\n },\\n \"availableIngredients\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nHow often should I include protein in my vegetarian meals?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request c7d86ede-d14b-4121-82a0-4cec64aee8e3.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 43099258-3bba-4655-952a-f73cab2c5e17: prompt: '<|im_start|>situation\\nYou are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Utilize the findRecipesBasedOnIngredients function to suggest recipes tailored to the users\\' available ingredients. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findRecipesBasedOnIngredients\",\\n \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"ingredients\": {\\n \"type\": \"array\",\\n \"items\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI found some spinach, feta cheese, and eggs in my fridge. What can I make for breakfast?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 43099258-3bba-4655-952a-f73cab2c5e17.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 8ac494de-c4ac-4c92-be32-406f30337a44: prompt: '<|im_start|>situation\\nYou are a Recipe and Meal Planner AI, tasked with helping users discover delicious meals they can cook with the ingredients they have. Jane Doe is a busy software developer who loves to unwind by cooking. She prefers quick, healthy meals due to her hectic schedule and likes to use whatever ingredients she already has.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findRecipesBasedOnIngredients\",\\n \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"ingredients\": {\\n \"type\": \"array\",\\n \"items\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the best way to store fresh spinach?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request 8ac494de-c4ac-4c92-be32-406f30337a44.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request cce72650-de48-4c10-ba37-fbb31cc083aa: prompt: '<|im_start|>situation\\nYou are a Health Monitoring Agent responsible for keeping track of users\\' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logHealthMetric\",\\n \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"metricName\": {\\n \"type\": \"string\"\\n },\\n \"value\": {\\n \"type\": \"number\"\\n },\\n \"timestamp\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI just finished my evening run. Can you log my heart rate and distance?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:110] Finished request cce72650-de48-4c10-ba37-fbb31cc083aa.\n", - "INFO 02-15 20:55:41 async_llm_engine.py:431] Received request 078d96d4-2471-4f20-baaa-60a7c49b512e: prompt: '<|im_start|>situation\\nYou are a Health Monitoring Agent responsible for keeping track of users\\' health metrics and providing insights to help them reach their health goals. You have access to a tool that logs health data, logHealthMetric, for accurate monitoring and analysis. Maria is a 35-year-old working professional aiming to improve her cardiovascular health after a recent high blood pressure diagnosis. She values detailed tracking and insights into her daily activities and health metrics.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"logHealthMetric\",\\n \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"metricName\": {\\n \"type\": \"string\"\\n },\\n \"value\": {\\n \"type\": \"number\"\\n },\\n \"timestamp\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you remind me why staying hydrated is important for my heart?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:110] Finished request 078d96d4-2471-4f20-baaa-60a7c49b512e.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:431] Received request fe3bc03b-d57c-48ac-af57-994502f80878: prompt: '<|im_start|>situation\\nYou are a Travel Planner Agent, responsible for helping users plan their trips efficiently. A tool available to you is findBestFlight(options), which finds the best flight options based on user preferences. Maria is a busy professional who loves to travel but doesn\\'t have time to sift through countless websites to find the best flights and deals for her vacation.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findBestFlight\",\\n \"description\": \"Finds the best flight options based on user preferences.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"options\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dates\": {\\n \"type\": \"string\"\\n },\\n \"destinations\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nI need to plan a trip to Paris from New York for my anniversary. It needs to be in June, and we\\'re looking for the best deals.<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:110] Finished request fe3bc03b-d57c-48ac-af57-994502f80878.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:431] Received request 1d0ec079-6c91-49fd-9d9c-35d134e8982b: prompt: '<|im_start|>situation\\nYou are a Travel Planner Agent, responsible for helping users plan their trips efficiently. Maria is a busy professional who loves to travel but doesn\\'t have time to sift through countless websites to find the best flights and deals for her vacation.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findBestFlight\",\\n \"description\": \"Finds the best flight options based on user preferences.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"options\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"dates\": {\\n \"type\": \"string\"\\n },\\n \"destinations\": {\\n \"type\": \"string\"\\n },\\n \"budget\": {\\n \"type\": \"number\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you recommend a romantic restaurant in Paris?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:110] Finished request 1d0ec079-6c91-49fd-9d9c-35d134e8982b.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:431] Received request dc41518e-285f-49a1-9d8b-23419fbce9c9: prompt: '<|im_start|>situation\\nYou are an E-commerce Shopping Assistant designed to help users find the best products online. You have access to a tool called \\'findProduct\\', which searches for products based on specific queries and filters. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findProduct\",\\n \"description\": \"Searches for products based on a user\\'s query and optional filters.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"query\": {\\n \"type\": \"string\"\\n },\\n \"filters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"priceRange\": {\\n \"type\": \"string\"\\n },\\n \"category\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nCan you find me a wireless mouse under $50 that\\'s great for gaming?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:110] Finished request dc41518e-285f-49a1-9d8b-23419fbce9c9.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:431] Received request 5d323d08-c5a5-4a90-88bd-176c0d5c65b2: prompt: '<|im_start|>situation\\nYou are an E-commerce Shopping Assistant designed to help users find the best products online. Alex is a busy professional with a keen interest in technology and gadgets, always looking for the latest tech products but has little time to browse through multiple online stores.<|im_end|>\\n<|im_start|>functions\\nAvailable functions:\\n\\n{\\n \"name\": \"findProduct\",\\n \"description\": \"Searches for products based on a user\\'s query and optional filters.\",\\n \"parameters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"query\": {\\n \"type\": \"string\"\\n },\\n \"filters\": {\\n \"type\": \"object\",\\n \"properties\": {\\n \"priceRange\": {\\n \"type\": \"string\"\\n },\\n \"category\": {\\n \"type\": \"string\"\\n }\\n }\\n }\\n }\\n }\\n}<|im_end|>\\n<|im_start|>person\\nWhat\\'s the difference between a mechanical keyboard and a membrane keyboard?<|im_end|>\\n<|im_start|>', prefix_pos: None,sampling params: SamplingParams(n=1, best_of=1, presence_penalty=0.0, frequency_penalty=0.0, repetition_penalty=1.0, temperature=0, top_p=1.0, top_k=-1, min_p=0.0, use_beam_search=False, length_penalty=1.0, early_stopping=False, stop=[], stop_token_ids=[], include_stop_str_in_output=False, ignore_eos=False, max_tokens=1, logprobs=None, prompt_logprobs=None, skip_special_tokens=True, spaces_between_special_tokens=True), prompt token ids: None, lora_request: None.\n", - "INFO 02-15 20:55:42 async_llm_engine.py:110] Finished request 5d323d08-c5a5-4a90-88bd-176c0d5c65b2.\n" - ] - } - ], - "source": [ - "reset_requests()\n", - "for example in example_prompts:\n", - " for key in [\"positive\", \"negative\"]:\n", - " prompt = example[key]\n", - " if not prompt:\n", - " continue\n", - " \n", - " logits_processors = [\n", - " # drop_disallowed_tokens,\n", - " get_lp(key, prompt),\n", - " ]\n", - " \n", - " await generate(prompt, logits_processors=logits_processors, max_tokens=1)" - ] - }, - { - "cell_type": "markdown", - "id": "8421f8bd-ab08-40fb-87bd-3aacd5ee200f", - "metadata": {}, - "source": [ - "## Analyze tags" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "dcbd2b9e-ba77-4816-b500-0d9f2b083863", - "metadata": {}, - "outputs": [], - "source": [ - "from torch.nn import functional as F\n", - "\n", - "get_tag_logits = lambda idx: {\n", - " tag: requests[type][idx][2][id]\n", - " for tag, id in tag_id_map.items()\n", - "}\n", - "\n", - "get_tag_probs = lambda idx: {\n", - " tag: F.softmax(requests[type][idx][2], dim = -1)[id]\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "ca70493e-2927-4324-9f31-beaf68225bcb", - "metadata": {}, - "outputs": [], - "source": [ - "tag_first_token_ids = list(id_tag_map.keys())" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "8dc59b5d-a5c8-4b51-a91d-aadd21516f8b", - "metadata": {}, - "outputs": [], - "source": [ - "def get_dist(type, idx, upper=50, lower=-2, output_probs=False):\n", - " if output_probs:\n", - " values = F.softmax(requests[type][idx][2], dim=-1)\n", - " else:\n", - " values = requests[type][idx][2]\n", - " \n", - " values = values.tolist()\n", - " \n", - " return [min(upper, max(lower, v)) for v in values]" - ] - }, - { - "cell_type": "markdown", - "id": "f8292ea9-df95-47dd-bcd3-911123bda6de", - "metadata": {}, - "source": [ - "## Visualize" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "af66c128-2dde-4ea2-b7e5-14af3968399f", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from mplcursors import cursor\n", - "\n", - "# Plotting\n", - "def plot(type, idx, output_probs=False):\n", - " dist = get_dist(type, idx, output_probs=output_probs)\n", - "\n", - " plt.clf()\n", - " plt.figure(figsize=(15, 6))\n", - " plt.plot(dist, marker='o', linestyle='-', color='blue')\n", - " plt.title(f'Plot of result {idx}')\n", - " plt.xlabel('Index')\n", - " plt.ylabel('Logit')\n", - " \n", - " # Highlighting tags\n", - " # b : blue · g : green · r : red · c : cyan · m : magenta · y : yellow · k : black\n", - " colors = \"b,g,r,c,m,y,k\".split(',')\n", - " \n", - " for (tag, id), color in zip(tag_id_map.items(), colors):\n", - " plt.axvline(x=id, color=color, linestyle='--', label=tag) # Indices are 0-based\n", - "\n", - " # Dotted horizontal line on zero\n", - " plt.axhline(y=0, color='y', linestyle=':', label='y=0 Line')\n", - "\n", - " plt.legend()\n", - " cursor(hover=True)\n", - "\n", - " plt.show()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "5b88522c-456d-430b-94dc-cc61a913047c", - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib widget\n", - "show = lambda type, idx, output_probs=False: (requests[type][idx][0], plot(type, idx, output_probs))" - ] - }, - { - "cell_type": "markdown", - "id": "0798a8d3-8b17-4e5c-9c90-919bf16bda17", - "metadata": {}, - "source": [ - "### Positive samples\n", - "> (where a function should be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "7e972a94-0df8-4df1-b3e6-76c6df9495cf", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "62b7684acc384ed297dc3caa135dedd9", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Text(value='positive', description='type'), IntSlider(value=0, description='idx', max=8)…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(type, idx, output_probs=False)>" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "a27417cab74243b58c82187087c80477", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAIyUlEQVR4nO3WMQEAIAzAMMC/5+ECjiYKenbPzCwAADLO7wAAAN4ygAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIMIABAjAEEAIgxgAAAMQYQACDGAAIAxBhAAIAYAwgAEGMAAQBiDCAAQIwBBACIMYAAADEGEAAgxgACAMQYQACAGAMIABBjAAEAYgwgAECMAQQAiDGAAAAxBhAAIMYAAgDEGEAAgBgDCAAQYwABAGIuJnkHvKensmIAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import ipywidgets as wg\n", - "\n", - "wg.interact(show, type=\"positive\", idx=wg.IntSlider(min=0, max=len(requests[\"positive\"])-1, step=1))" - ] - }, - { - "cell_type": "markdown", - "id": "c84d7a4e-8f25-430b-8131-ed121d1b713d", - "metadata": {}, - "source": [ - "### Negative samples\n", - "> (where functions should NOT be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "21888f23-fb08-464a-a12e-f92f9bbac7a5", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "6c3c4dc810e149308f1abefcbfc4f2ec", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "interactive(children=(Text(value='negative', description='type'), IntSlider(value=0, description='idx', max=10…" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "(type, idx, output_probs=False)>" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "wg.interact(show, type=\"negative\", idx=wg.IntSlider(min=0, max=len(requests[\"negative\"])-1, step=1))" - ] - }, - { - "cell_type": "code", - "execution_count": 102, - "id": "bfee96d3-5343-47a4-ade6-4718caf1cbe4", - "metadata": {}, - "outputs": [], - "source": [ - "get_points = lambda type, select_tags: [\n", - " req[2].tolist()\n", - " if select_tags is None\n", - " else [\n", - " req[2][tag_id_map[tag]].item()\n", - " for tag in select_tags\n", - " ]\n", - " for req in requests[type]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 103, - "id": "541e5e0e-c9a4-4464-a635-da44496fac19", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", [\"me\", \"function_call\"])\n", - "negative_points = get_points(\"negative\", [\"me\", \"function_call\"])\n", - "\n", - "positive_xs, positive_ys = zip(*positive_points)\n", - "negative_xs, negative_ys = zip(*negative_points)\n", - "\n", - "xs = positive_xs + negative_xs\n", - "ys = positive_ys + negative_ys\n", - "colors = ['b']*len(positive_xs) + ['r']*len(negative_xs)" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "id": "d4e8f9f0-3fed-432e-92cc-2389f33b23a8", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8fcd2e1a70ba4c05a6ba8839c1cd48c3", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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Mw4AAACqSeEOPcjf/m3yk58k7373q/tqapIjj0x+9atkxx2rFg3gTRk5Mtl++87HrFuXHHBA9+QBAACAt6JULpszRt/Q1NSU+vr6NDY2pq6urtpx3rKFC5PGxkpRtc021U4D8OZddlkybVr7s9hraiql/KJFlU/zAAAAFKG39URsPvzTFXqoXXapdgKAYnz605VP6dxwQ6Vg37Chsr+mJqmrS269VdkOAABAz2BJGQCgqmpqkuuuS2bOTA45JHnHO5LRo5MvfSl57LFkzJhqJwQAAIBNY74YAFB1/folRxxR2QAAAKCnMsMdAAAAAAAKoHAHAAAAAIACKNwBAAAAAKAACncAAAAAACiAwh0AAAAAAAqgcAcAAAAAgAIo3CnUxRdfnH333TdDhgzJtttumylTpmTBggWtx//0pz/l05/+dHbfffcMGjQo22+/fT7zmc+ksbGx0+uefPLJKZVKbbZJkyZ19dsBAAAAANhkCncKNWfOnJx++umZO3du7rjjjqxbty4TJkzI2rVrkyTPPvtsnn322Xzzm9/Mo48+munTp+f222/PqaeeutFrT5o0KUuXLm3dbrjhhq5+OwCFaGpKli1L1q+vdhKAzdOLLyZLlyYvvVTtJAAA8NaUyuVyudoh6L2ef/75bLvttpkzZ04OOOCAdsf86Ec/ysc//vGsXbs2tbW17Y45+eSTs2rVqsycOfNNZ2lqakp9fX0aGxtTV1f3pq8DsKlmzUq+8pXk7rsrr4cOTU47LfnHf0y23LKq0QA2C08+mfzzPyc33pisW5f0759MnZqcf36yyy7VTgcA9GZ6IrqKGe50qVeWihk6dGinY+rq6jos219x9913Z9ttt83uu++e0047LStXrux0fHNzc5qamtpsAN3lhz9MPvzh5N57X933pz8lX/1qcuCByZo11csGsDl49NHkve9NbrihUrYnycsvJ//1X5X9//u/1c0HAABvhhnudJmWlpYcfvjhWbVqVe677752x6xYsSJjx47Nxz/+8fzLv/xLh9e68cYb87a3vS077bRTFi5cmPPOOy9bbrllHnjggdTU1LR7zoUXXpiLLrrodfv95hLoaitXJg0NleKoPTU1yXnnVWZ1Ul0LFlQ+gVAuJ/vvn+y1V7UTQd/xvvcl8+YlGza8/lhNTeX4/fd3fy4AoG8ww52uonCny5x22mn52c9+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psfY2PetCy+8MKNHj87gwYPz9re/PePHj8+DDz5YnbD0KBu7t/7Spz71qZRKpVx22WXdlo+ea2P31sknn5xSqdRmmzRpUnXC0qNsyvetxx57LIcffnjq6+szePDg7Lvvvlm8eHH3h6VH2di99drvWa9s3/jGN6oTmB5jY/fWmjVrcsYZZ2S77bbLoEGD8q53vStXXXVVdcLCZkrhDpu5tWvXZsyYMbniiis6PL7//vvna1/7Wjcno6fr7N564YUXMm/evJx//vmZN29ebr755ixYsCCHH354FZLS02zs+9Zuu+2Wyy+/PI888kjuu+++7LjjjpkwYUKef/75bk5KT7Oxe+sVM2bMyNy5c9PQ0NBNyejpNuXemjRpUpYuXdq63XDDDd2YkJ5qY/fWwoULs//++2f06NG5++6789vf/jbnn39+Bg4c2M1J6Wk2dm/95ferpUuX5pprrkmpVMrRRx/dzUnpaTZ2b02bNi233357rrvuujz22GM588wzc8YZZ+SWW27p5qSw+SqVy+VytUMAm6ZUKmXGjBmZMmXK64499dRT2WmnnfKb3/wm++yzT7dno2fr7N56xa9//eu8733vy9NPP53tt9+++8LRo23KvdXU1JT6+vrceeedOeSQQ7ovHD1aR/fWH//4x4wbNy4///nPc+ihh+bMM8/MmWeeWZWM9Ezt3Vsnn3xyVq1a1emnKmBj2ru3jj/++GyxxRb54Q9/WL1g9Hib8t9bU6ZMyerVqzNr1qzuC0aP1969tddee+W4447L+eef37pv7NixmTx5cr7yla9UISVsfsxwB2CTNDY2plQqZauttqp2FHqRl19+Od/97ndTX1+fMWPGVDsOPVxLS0tOOOGEnHPOOdlzzz2rHYde5u677862226b3XffPaeddlpWrlxZ7Uj0cC0tLbntttuy2267ZeLEidl2220zbtw4v9ihcMuXL89tt92WU089tdpR6AU+8IEP5JZbbskf//jHlMvlzJ49O7///e8zYcKEakeDzYbCHYCNeumll/KFL3whU6dOTV1dXbXj0Avceuut2XLLLTNw4MD827/9W+64445ss8021Y5FD/e1r30ttbW1+cxnPlPtKPQykyZNyg9+8IPMmjUrX/va1zJnzpxMnjw5GzZsqHY0erDnnnsua9asyVe/+tVMmjQpv/jFL3LkkUfmqKOOypw5c6odj17k2muvzZAhQ3LUUUdVOwq9wLe//e28613vynbbbZf+/ftn0qRJueKKK3LAAQdUOxpsNmqrHQCAzdu6dety7LHHplwu58orr6x2HHqJgw8+OPPnz8+KFSvyve99L8cee2wefPDBbLvtttWORg/18MMP59///d8zb968lEqlasehlzn++ONb/7733nvn3e9+d3bZZZfcfffdlsLiTWtpaUmSHHHEEfnc5z6XJNlnn31y//3356qrrsqBBx5YzXj0Itdcc00+9rGPeTYAhfj2t7+duXPn5pZbbskOO+yQe+65J6effnoaGhoyfvz4aseDzYIZ7gB06JWy/emnn84dd9xhdjuFGTx4cHbddde8//3vz9VXX53a2tpcffXV1Y5FD3bvvffmueeey/bbb5/a2trU1tbm6aefzllnnZUdd9yx2vHoZXbeeedss802efLJJ6sdhR5sm222SW1tbd71rne12b/HHntk8eLFVUpFb3PvvfdmwYIF+cQnPlHtKPQCL774Ys4777xceumlOeyww/Lud787Z5xxRo477rh885vfrHY82GyY4Q5Au14p25944onMnj07W2+9dbUj0Yu1tLSkubm52jHowU444YTXzaqaOHFiTjjhhJxyyilVSkVv9cwzz2TlypUZOXJktaPQg/Xv3z/77rtvFixY0Gb/73//++ywww5VSkVvc/XVV2fs2LGelUMh1q1bl3Xr1qVfv7bzd2tqalo/tQMo3GGzt2bNmjazpxYtWpT58+dn6NCh2X777fOnP/0pixcvzrPPPpskrf/BPmLEiIwYMaIqmekZOru3Ro4cmWOOOSbz5s3Lrbfemg0bNmTZsmVJkqFDh6Z///7Vik0P0Nm9tfXWW+df/uVfcvjhh2fkyJFZsWJFrrjiivzxj3/MRz/60SqmpifY2M/E1/5icIsttsiIESOy++67d3dUepjO7q2hQ4fmoosuytFHH50RI0Zk4cKF+fznP59dd901EydOrGJqeoKNfd8655xzctxxx+WAAw7IwQcfnNtvvz0/+clPcvfdd1cvND3Cxu6tJGlqasqPfvSjXHLJJdWKSQ+0sXvrwAMPzDnnnJNBgwZlhx12yJw5c/KDH/wgl156aRVTw2amDGzWZs+eXU7yuu2kk04ql8vl8ve///12j19wwQVVzc3mr7N7a9GiRe0eS1KePXt2taOzmevs3nrxxRfLRx55ZLmhoaHcv3//8siRI8uHH354+Ve/+lW1Y9MDbOxn4mvtsMMO5X/7t3/r1oz0TJ3dWy+88EJ5woQJ5WHDhpW32GKL8g477FD+5Cc/WV62bFm1Y9MDbMr3rauvvrq86667lgcOHFgeM2ZMeebMmdULTI+xKffWf/zHf5QHDRpUXrVqVfWC0uNs7N5aunRp+eSTTy43NDSUBw4cWN59993Ll1xySbmlpaW6wWEzUiqXy+WCO3wAAAAAAOhzPDQVAAAAAAAKoHAHAAAAAIACKNwBAAAAAKAACncAAAAAACiAwh0AAAAAAAqgcAcAAAAAgAIo3AEAAAAAoAAKdwAAAAAAKIDCHQAAAAAACqBwBwAAAACAAijcAQAAAACgAAp3AAAAAAAogMIdAAAAAAAKoHAHAAAAAIACKNwBAAAAAKAACncAAAAAACiAwh0AAAAAAAqgcAcAAAAAgAIo3AEAAAAAoAAKdwAAAAAAKIDCHQAAAAAACqBwBwAAAACAAijcAQAAAACgAAp3AAAAAAAogMIdAAAAAAAKoHAHAAAAAIACKNwBAAAAAKAACncAAAAAACiAwh0AAAAAAAqgcAcAAAAAgAIo3AEAAAAAoAAKdwAAAAAAKIDCHQAAAAAACqBwBwAAAACAAijcAQAAAACgAAp3AAAAAAAogMIdAAAAAAAKoHAHAAAAAIACKNwBAAAAAKAACncAAAAAACiAwh0AAAAAAAqgcAcAAAAAgAIo3AEAAAAAoAAKdwAAAAAAKMD/DwhbJg94u10PAAAAAElFTkSuQmCC", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure 3\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "f142efa1-dbcb-4bee-b78e-a4686b0e88ac", - "metadata": {}, - "source": [ - "## PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 110, - "id": "bd0bd893-6201-4e4b-a254-c1f520de3221", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.decomposition import KernelPCA, PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 116, - "id": "cb764bc0-d2d3-490f-900c-540bdb201390", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", tags)\n", - "negative_points = get_points(\"negative\", tags)\n", - "\n", - "p_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "n_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "# p_pca = PCA(n_components=2)\n", - "# n_pca = PCA(n_components=2)\n", - "\n", - "positive_points_t = p_pca.fit_transform(np.array(positive_points))\n", - "negative_points_t = n_pca.fit_transform(np.array(negative_points))" - ] - }, - { - "cell_type": "code", - "execution_count": 117, - "id": "0d6a09a8-fd3e-4b23-bf27-6634a2ebf98a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[-0.04758799, -0.04601498],\n", - " [ 0.15804275, -0.02781785],\n", - " [ 0.06866472, 0.00021807],\n", - " [ 0.07392165, 0.04305744],\n", - " [ 0.01155016, -0.01838244],\n", - " [-0.03798287, 0.02512603],\n", - " [-0.03151236, 0.05122014],\n", - " [-0.0825673 , -0.04320429],\n", - " [-0.11252875, 0.01579788]])" - ] - }, - "execution_count": 117, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "positive_points_t" - ] - }, - { - "cell_type": "code", - "execution_count": 118, - "id": "e4f1dba6-aeb9-4f30-ae7c-0359c9c161f4", - "metadata": {}, - "outputs": [], - "source": [ - "positive_xs, positive_ys = zip(*positive_points_t)\n", - "negative_xs, negative_ys = zip(*negative_points_t)\n", - "\n", - "xs = positive_xs + negative_xs\n", - "ys = positive_ys + negative_ys\n", - "colors = ['b']*len(positive_xs) + ['r']*len(negative_xs)" - ] - }, - { - "cell_type": "code", - "execution_count": 119, - "id": "c1a621bb-b164-4ff2-9389-802b944db4ee", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8fcd2e1a70ba4c05a6ba8839c1cd48c3", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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9Wr3VVm5snp3UwAAAADWmCvcWa0zzjhjlTctfe32wAMP9OsMZ511Vt71rndlt912y+mnn57TTjstX/3qV/t8zpw5c9La2tq9jR8/vl9nhPXKaadVr2JvXMW3gaam5J3vTKZNq/1cAAAAAOsxwZ3VOuWUU3L//ff3uW299dYZM2ZMnn766R7PXblyZZ5//vmM6eUuiGPGjMny5cuzePHiHvsXLVrU63OSZPLkyXniiSd6XMH+erNmzUp7e3v39vjjj6/5m4bBbuedk5tuSl757ZINNkia//eXnvbaK5k7txreAQAAAFhjlpRhtTbffPNsvvnmqz1uypQpWbx4cRYsWJBJkyYlSX7605+mq6srkydPXuVzJk2alA022CDz5s3LIYcckiR58MEH89hjj2XKlCm9fq277747m266aYb3sQ718OHD+3wchrw//dPkySerN0a9667quu4HHZRMnlxddgYAAACAtdJQcedJCjrggAOyaNGiXHLJJVmxYkWOOuqo7L777rnqqquSJE8++WT222+/XHnlldlzzz2TJMcee2xuuummXH755Wlpacnxxx+fJLntttuSJD/60Y+yaNGi7LXXXhkxYkRuueWWnHrqqTn11FPz+c9/fo1nc/dpAAAAABKdiP7jCneK+t73vpfjjjsu++23XxobG3PIIYfk61//evfjK1asyIMPPpiXXnqpe9/f/u3fdh+7bNmyTJs2Ld/4xje6H99ggw1y8cUX5+STT06lUsm2226bCy64IJ/85Cdr+t4AAAAAAPriCneGDD+5BAAAACDRieg/bpoKAAAAAAAFCO4AAAAAAFCA4A4AAAAAAAUI7gAAAAAAUIDgDgAAAAAABQjuAAAAAABQgOAOAAAAAAAFCO4AAAAAAFCA4A5AfXV1JR0dycqV9Z4EAAAA4E0R3AGoj6eeSk46KWltrW6bbJL81V8lv/tdvScDAAAAWCeCOwC199hjyaRJyUUXJS++WN338svJFVdU9//3f9d3PgAAAIB1ILgDUHvHHps880zS2dlz/8qV1QD/F3+RVCr1mQ0AAABgHQnuANTW//xP8uMf975me2dncs89ye2313au3ixZkvz2t9Wr8gEAAAD6ILgDUFv33bdmV6/fc0//z9KXp59Ojj462Xzz5B3vSN761mS33ZIf/ai+cwEAAAADluAOQG1tuGHZ4/rD008nkycnV16ZLFv26v7//u/k4IOTyy6r32wAAADAgCW4A7D2Hn00Oe20ZIcdkm22ST7+8TVfAmbKlGTkyL6PaW5Opk17s1Ouu3POSR5//I3L3nR1VT9++tPJCy/UfCwAAABgYBPcAVg7N99cDe0XXJA88EDy+98nV1+d7LVX8pWvrP75I0Ykp5/e++ONjclf/3V1KZd6+MMfkssvf+MNXV9r+fLkqqtqNhIAAACwfhDcAVhzzzyTfPjD1eD82iD9ypXgp5+e/OQnq3+d005LTjih+nlzc9LUVP2YJB/9aDXm10tbWzW696W5OXnoodrMAwAAAKw3mus9AADrkW9/O3n55VeXVnm9pqZqLJ86te/XaWxM/u7vqkuzXH55dfmWLbaoLk2z227Fx14rLS2rP6ZSWbPjAAAAgCFFcAdgzf3sZ73H9qR61fvPfrbmr/f2tydz5rz5uUp6y1uS9743+cUvel9WZuXK6pX4AAAAAK9hSRkAeL1zzqlexd7Q8MbHGhuTQw5Jdtqp5mMBAAAAA5vgDsCa23ffanDuTXNz9Zj13b77Jv/yL8kmm1T/vMEG1eVykuTQQ5Mrr6zfbAAAAMCA1VCpVCr1HgJqoaOjI62trWlvb0+LtZdh3TzzTDJhQt/ruN9yy+rXcF9fvPRSNbw/8ECy8cbVK9vf/vZ6TwUAAMCbpBPRX6zhDsCa23zz5Lrrkg99KFmx4tU1zpubq+uan3fe4IntSbLRRsmRR9Z7CgAAAGA9IbgDsHY+8IHk/vuTb34z+dGPkuXLk733To47Ltlzz3pPBwAAAFA3lpRhyPCrQgAAAAAkOhH9x01TAQAAAACgAMEdAAAAAAAKENwBAAAAAKAAwR0AAAAAAAoQ3AEAAAAAoADBHQAAAAAAChDcAQAAAACgAMEdAAAAAAAKENwBAAAAAKAAwR0AAAAAAAoQ3AEAAAAAoADBHQAAAAAAChDcAQAAAACgAMEdAAAAAAAKaK73AFArlUolSdLR0VHnSQAAAACop1f60Cu9CEoR3BkylixZkiQZP358nScBAAAAYCBYsmRJWltb6z0Gg0hDxY9xGCK6urqycOHCbLLJJmloaKj3OANSR0dHxo8fn8cffzwtLS31HgfWG84dWDfOHVg3zh1Ye84bWDeD+dypVCpZsmRJxo0bl8ZGq25TjivcGTIaGxuz1VZb1XuM9UJLS8ug+0YKteDcgXXj3IF149yBtee8gXUzWM8dV7bTH/z4BgAAAAAAChDcAQAAAACgAMEd6DZ8+PDMnj07w4cPr/cosF5x7sC6ce7AunHuwNpz3sC6ce7A2nPTVAAAAAAAKMAV7gAAAAAAUIDgDgAAAAAABQjuAAAAAABQgOAOAAAAAAAFCO4wxD3//PM54ogj0tLSkpEjR+boo4/Oiy++2Ofxxx9/fN7+9rdnww03zB//8R/nhBNOSHt7ew2nhtq7+OKLM2HChIwYMSKTJ0/OHXfc0efx1157bbbffvuMGDEiO++8c2666aYaTQoDy9qcO5deemne/e53Z9NNN82mm26aqVOnrvZcg8Fobb/nvOLqq69OQ0NDpk+f3r8DwgC1tufO4sWL85nPfCZjx47N8OHD87a3vc3f2RiS1vbcufDCC7ubwPjx43PyySfn5ZdfrtG0MPAJ7jDEHXHEEbnvvvtyyy235MYbb8zPf/7zHHPMMb0ev3DhwixcuDDnn39+7r333lx++eWZO3dujj766BpODbV1zTXXZObMmZk9e3buvPPO7Lrrrpk2bVqefvrpVR5/22235fDDD8/RRx+du+66K9OnT8/06dNz77331nhyqK+1PXduvfXWHH744fmP//iPzJ8/P+PHj88HPvCBPPnkkzWeHOpnbc+bVzz66KM59dRT8+53v7tGk8LAsrbnzvLly/P+978/jz76aP7lX/4lDz74YC699NJsueWWNZ4c6mttz52rrroqZ5xxRmbPnp37778/3/72t3PNNdfks5/9bI0nh4GroVKpVOo9BFAf999/f3bcccf8+te/zu67754kmTt3bg488MA88cQTGTdu3Bq9zrXXXpu/+Iu/yNKlS9Pc3NyfI0NdTJ48OXvssUcuuuiiJElXV1fGjx+f448/PmecccYbjp8xY0aWLl2aG2+8sXvfXnvtlYkTJ+aSSy6p2dxQb2t77rxeZ2dnNt1001x00UU58sgj+3tcGBDW5bzp7OzMe97znvyf//N/8otf/CKLFy/O9ddfX8Opof7W9ty55JJL8tWvfjUPPPBANthgg1qPCwPG2p47xx13XO6///7Mmzeve98pp5yS22+/Pb/85S9rNjcMZK5whyFs/vz5GTlyZHdsT5KpU6emsbExt99++xq/Tnt7e1paWsR2BqXly5dnwYIFmTp1ave+xsbGTJ06NfPnz1/lc+bPn9/j+CSZNm1ar8fDYLQu587rvfTSS1mxYkU222yz/hoTBpR1PW++8IUvZIsttvAbhwxZ63Lu3HDDDZkyZUo+85nPZPTo0dlpp53ypS99KZ2dnbUaG+puXc6dvffeOwsWLOhedub3v/99brrpphx44IE1mRnWB+oYDGFtbW3ZYosteuxrbm7OZpttlra2tjV6jWeffTbnnntun8vQwPrs2WefTWdnZ0aPHt1j/+jRo/PAAw+s8jltbW2rPH5NzysYDNbl3Hm9008/PePGjXvDD7BgsFqX8+aXv/xlvv3tb+fuu++uwYQwMK3LufP73/8+P/3pT3PEEUfkpptuysMPP5xPf/rTWbFiRWbPnl2LsaHu1uXc+djHPpZnn302++yzTyqVSlauXJlPfepTlpSB13CFOwxCZ5xxRhoaGvrc1jR29KWjoyMf/OAHs+OOO+acc85584MDwP/68pe/nKuvvjrXXXddRowYUe9xYEBasmRJPv7xj+fSSy/NqFGj6j0OrFe6urqyxRZb5Fvf+lYmTZqUGTNm5HOf+5zl/2A1br311nzpS1/KN77xjdx55535wQ9+kH/7t3/LueeeW+/RYMBwhTsMQqecckr+8i//ss9jtt5664wZM+YNN0JZuXJlnn/++YwZM6bP5y9ZsiT7779/Ntlkk1x33XXWPWTQGjVqVJqamrJo0aIe+xctWtTreTJmzJi1Oh4Go3U5d15x/vnn58tf/nJ+8pOfZJdddunPMWFAWdvz5ne/+10effTRHHTQQd37urq6klR/a/HBBx/MNtts079DwwCwLt9zxo4dmw022CBNTU3d+3bYYYe0tbVl+fLlGTZsWL/ODAPBupw7Z511Vj7+8Y/nr/7qr5IkO++8c5YuXZpjjjkmn/vc59LY6NpecBbAILT55ptn++2373MbNmxYpkyZksWLF2fBggXdz/3pT3+arq6uTJ48udfX7+joyAc+8IEMGzYsN9xwgysPGdSGDRuWSZMm9bgpUFdXV+bNm5cpU6as8jlTpkzpcXyS3HLLLb0eD4PRupw7SfKVr3wl5557bubOndvjHiMwFKztebP99tvnnnvuyd133929HXzwwXnf+96Xu+++O+PHj6/l+FA36/I9513velcefvjh7h9SJcn/+3//L2PHjhXbGTLW5dx56aWX3hDVX/nBVaVS6b9hYT3iCncYwnbYYYfsv//++eQnP5lLLrkkK1asyHHHHZfDDjss48aNS5I8+eST2W+//XLllVdmzz337I7tL730Ur773e+mo6MjHR0dSaqh/7VXiMBgMXPmzHziE5/I7rvvnj333DMXXnhhli5dmqOOOipJcuSRR2bLLbfMnDlzkiQnnnhi9t1333zta1/LBz/4wVx99dX5zW9+k29961v1fBtQc2t77px33nk5++yzc9VVV2XChAnd9z3YeOONs/HGG9ftfUAtrc15M2LEiOy00049nj9y5MgkecN+GOzW9nvOsccem4suuignnnhijj/++Dz00EP50pe+lBNOOKGebwNqbm3PnYMOOigXXHBBdtttt0yePDkPP/xwzjrrrBx00EF6APwvwR2GuO9973s57rjjst9++6WxsTGHHHJIvv71r3c/vmLFijz44IN56aWXkiR33nlnbr/99iTJtttu2+O1HnnkkUyYMKFms0OtzJgxI88880zOPvvstLW1ZeLEiZk7d273zYUee+yxHld57L333rnqqqty5pln5rOf/Wy22267XH/99eIHQ87anjvf/OY3s3z58hx66KE9Xmf27NnuFcKQsbbnDVC1tufO+PHj8+///u85+eSTs8suu2TLLbfMiSeemNNPP71ebwHqYm3PnTPPPDMNDQ0588wz8+STT2bzzTfPQQcdlL/5m7+p11uAAaeh4vc9AAAAAADgTXNpBAAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAYI7AAAAAAAUILgDAAAAAEABgjsAAAAAABQguAMAAAAAQAGCOwAAAAAAFCC4AwAAAABAAf8fVECMhsgnlegAAAAASUVORK5CYII=", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure 3\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4333abed-3cd8-423c-842e-585aa1d0c9bb", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/model-serving/notebooks/process_dataset-Copy1.ipynb b/model-serving/notebooks/process_dataset-Copy1.ipynb deleted file mode 100644 index 591450765..000000000 --- a/model-serving/notebooks/process_dataset-Copy1.ipynb +++ /dev/null @@ -1,697 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "80aa2ec0-bc54-478f-96a8-746c7b1be871", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"] = '0,1'" - ] - }, - { - "cell_type": "markdown", - "id": "3ec2cf2f-2041-4cd8-accc-759686c7a65f", - "metadata": {}, - "source": [ - "## Sample Functions (generated by gpt4)\n", - "> [ChatGPT Thread](https://chat.openai.com/share/6ed2d0bb-ec35-4273-85b8-113d37db7f43)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f2498009-32ec-4cfa-8853-2d762d69ae44", - "metadata": {}, - "outputs": [], - "source": [ - "sample_functions = dict(\n", - " personal_trainer={ \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } },\n", - " budget_assistant={\n", - " \"name\": \"categorizeTransaction\",\n", - " \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"transactionDescription\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " home_agent={\n", - " \"name\": \"adjustThermostat\",\n", - " \"description\": \"Adjusts the home's thermostat to the desired temperature and mode.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"temperature\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"mode\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner={\n", - " \"name\": \"fetchRecipes\",\n", - " \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dietaryPreferences\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"availableIngredients\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " educational_tutor={\n", - " \"name\": \"generatePersonalizedQuiz\",\n", - " \"description\": \"Creates a quiz tailored to the user's learning level and performance history in a specific subject.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"UserID\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"Subject\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"DifficultyLevel\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner={\n", - " \"name\": \"searchFlights\",\n", - " \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"destination\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"departureDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"returnDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"budget\": {\n", - " \"type\": \"number\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner_2={\n", - " \"name\": \"findRecipesBasedOnIngredients\",\n", - " \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"ingredients\": {\n", - " \"type\": \"array\",\n", - " \"items\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner_2={\n", - " \"name\": \"findBestFlight\",\n", - " \"description\": \"Finds the best flight options based on user preferences.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"options\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dates\": {\"type\": \"string\"},\n", - " \"destinations\": {\"type\": \"string\"},\n", - " \"budget\": {\"type\": \"number\"}\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " health_monitor={\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " ecommerce_assistant={\n", - " \"name\": \"findProduct\",\n", - " \"description\": \"Searches for products based on a user's query and optional filters.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"query\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"filters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"priceRange\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"category\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e3eb2fd-49c9-49e2-8406-bff4fc7b7f62", - "metadata": {}, - "source": [ - "## Process dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "41efaf92-9ae2-4756-a894-40dcd04c48cb", - "metadata": {}, - "outputs": [], - "source": [ - "from datasets import load_dataset\n", - "\n", - "ds = load_dataset(\"togethercomputer/glaive-function-calling-v2-formatted\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "baed17a9-747b-4188-8644-05f850e3f725", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.remove_columns(\"text\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "47eae24a-648d-4efe-934d-40010a45ec3f", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import random\n", - "\n", - "def convert_tools_to_functions(row):\n", - " tools = json.loads(row[\"tools\"])\n", - "\n", - " # Get functions\n", - " functions = (\n", - " # [tool[\"function\"] for tool in tools]\n", - " # if tools else\n", - " random.sample(list(sample_functions.values()), 1)\n", - " )\n", - "\n", - " return dict(\n", - " functions=json.dumps(functions), # hf datasets cant hold arbitrary types\n", - " use_function=False\n", - " )\n", - "\n", - "ds = ds.map(convert_tools_to_functions).remove_columns(\"tools\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "3f61f791-c44d-4165-bf5f-1abbc10e5ef1", - "metadata": {}, - "outputs": [], - "source": [ - "def replace_system_message(row):\n", - " situation_content = \"You are a helpful assistant with access to one or more tools. Use them only if required to fulfill a user's request.\"\n", - " messages = json.loads(row[\"messages\"])\n", - "\n", - " # Sanity check\n", - " assert messages[0][\"role\"] == \"system\"\n", - " \n", - " # Replace system message\n", - " messages[0] = dict(\n", - " role=\"system\",\n", - " name=\"situation\",\n", - " content=situation_content,\n", - " )\n", - "\n", - " return dict(\n", - " messages=messages[:2], # Only keep system and user messages\n", - " )\n", - "\n", - "ds = ds.map(replace_system_message)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "66e65bb5-da29-4808-87b6-cc9e503284bd", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.filter(lambda row: all(msg[\"content\"] for msg in row[\"messages\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "d3312b84-46f8-4c90-b8df-27582d986a3e", - "metadata": {}, - "outputs": [], - "source": [ - "from model_api.conversion.conversions import to_prompt, parse_message\n", - "from model_api.conversion.datatypes import ChatMLMessage\n", - "from model_api.protocol import FunctionDef\n", - "\n", - "# Convert to prompts\n", - "convert_to_prompt = lambda row: dict(\n", - " prompt=to_prompt(\n", - " messages=[\n", - " ChatMLMessage(**message)\n", - " for message in row[\"messages\"]\n", - " ],\n", - " functions=[\n", - " FunctionDef(**fn)\n", - " for fn in json.loads(row[\"functions\"])\n", - " ],\n", - " )\n", - ")\n", - "\n", - "ds = ds.map(convert_to_prompt)" - ] - }, - { - "cell_type": "markdown", - "id": "84e41df0-9095-402c-8e1b-b0ecc8f7748c", - "metadata": {}, - "source": [ - "## Start engine" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "174aa0cc-8697-44c0-a8dc-d5beb7ad39d0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AsyncEngineArgs(model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode='auto', trust_remote_code=False, download_dir=None, load_format='auto', dtype='bfloat16', kv_cache_dtype='auto', seed=0, max_model_len=None, worker_use_ray=False, pipeline_parallel_size=1, tensor_parallel_size=2, max_parallel_loading_workers=None, block_size=16, swap_space=4, gpu_memory_utilization=0.96, max_num_batched_tokens=None, max_num_seqs=512, max_paddings=256, disable_log_stats=False, revision=None, tokenizer_revision=None, quantization=None, enforce_eager=False, max_context_len_to_capture=8192, disable_custom_all_reduce=False, enable_lora=False, max_loras=1, max_lora_rank=16, lora_extra_vocab_size=256, max_cpu_loras=None, engine_use_ray=False, disable_log_requests=False, max_log_len=None)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo\",\n", - " dtype=\"bfloat16\",\n", - " enforce_eager=False,\n", - " tensor_parallel_size=2,\n", - " swap_space=4, # GiB\n", - " gpu_memory_utilization=0.96,\n", - " max_num_seqs=512,\n", - ")\n", - "\n", - "\n", - "engine_args" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "28cee360-ef57-4610-85a9-21b4981c8d0a", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-02-20 17:30:50,216\tINFO worker.py:1724 -- Started a local Ray instance.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 17:30:51 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=32768, download_dir=None, load_format=auto, tensor_parallel_size=2, disable_custom_all_reduce=False, quantization=None, enforce_eager=False, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 17:30:57 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:30:57 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "INFO 02-20 17:30:58 weight_utils.py:164] Using model weights format ['*.bin']\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:30:59 weight_utils.py:164] Using model weights format ['*.bin']\n", - "INFO 02-20 17:31:14 llm_engine.py:322] # GPU blocks: 4085, # CPU blocks: 4096\n", - "INFO 02-20 17:31:16 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "INFO 02-20 17:31:16 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:31:16 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:31:16 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "INFO 02-20 17:31:22 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "INFO 02-20 17:31:22 model_runner.py:698] Graph capturing finished in 7 secs.\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:31:22 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "\u001b[36m(RayWorkerVllm pid=351968)\u001b[0m INFO 02-20 17:31:22 model_runner.py:698] Graph capturing finished in 7 secs.\n" - ] - } - ], - "source": [ - "engine = AsyncLLMEngine.from_engine_args(engine_args)" - ] - }, - { - "cell_type": "markdown", - "id": "20fa04bf-8121-4262-a8e4-e8f3aed05153", - "metadata": {}, - "source": [ - "## Tokenize prompt" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "fcbaba94-bcb3-4c81-976c-7051200fbb13", - "metadata": {}, - "outputs": [], - "source": [ - "tokenizer = engine.engine.tokenizer.tokenizer\n", - "\n", - "ds = ds.map(\n", - " lambda row: dict(\n", - " prompt_token_ids=tokenizer.encode(row[\"prompt\"])\n", - " )\n", - ")\n", - "\n", - "# )[\"train\"][0][\"prompt_token_ids\"]" - ] - }, - { - "cell_type": "markdown", - "id": "b53a215c-edef-407f-a31a-6af425dac9cb", - "metadata": {}, - "source": [ - "## Prepare generator" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "a91773a5-a70f-488e-ad28-fc8223e80a57", - "metadata": {}, - "outputs": [], - "source": [ - "from uuid import uuid4\n", - "from vllm.sampling_params import SamplingParams\n", - "\n", - "def prep_generator(\n", - " prompt_token_ids,\n", - " temperature=0,\n", - " max_tokens=1,\n", - " logits_processors=[],\n", - " **sampling_kwargs,\n", - "):\n", - " sampling_params = SamplingParams(\n", - " temperature=temperature,\n", - " max_tokens=max_tokens,\n", - " logits_processors=logits_processors,\n", - " **sampling_kwargs,\n", - " )\n", - " \n", - " res_generator = engine.generate(\n", - " sampling_params=sampling_params,\n", - " request_id=uuid4(),\n", - " prompt=None,\n", - " prompt_token_ids=prompt_token_ids,\n", - " )\n", - "\n", - " return res_generator\n", - "\n", - "async def generate(\n", - " prompt_token_ids,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt_token_ids, **sampling_kwargs)\n", - " final_res = None\n", - "\n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res\n", - "\n", - "def generate_no_wait(\n", - " prompt_token_ids,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt_token_ids, **sampling_kwargs)\n", - "\n", - " async def waiter():\n", - " final_res = None\n", - " \n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res\n", - "\n", - " return waiter()" - ] - }, - { - "cell_type": "markdown", - "id": "c0248caf-b8a7-4cf2-80d4-e92e6396a39c", - "metadata": {}, - "source": [ - "## Prep logits processor" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "024b08d7-c0a1-4e22-99ff-038a65056b83", - "metadata": {}, - "outputs": [], - "source": [ - "# List of tags \n", - "allowed_tags = [\"me\", \"function_call\", \"thought\"]\n", - "disallowed_tags = [\"situation\", \"person\", \"functions\", \"information\"]\n", - "tags = allowed_tags + disallowed_tags\n", - "\n", - "allowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in allowed_tags\n", - "]\n", - "\n", - "disallowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in disallowed_tags\n", - "]\n", - "\n", - "tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in tags\n", - "]\n", - "\n", - "tag_id_map = {\n", - " tag: tag_ids[0]\n", - " for tag, tag_ids in zip(tags, tag_token_ids)\n", - "}\n", - "\n", - "id_tag_map = {\n", - " id: tag\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "cd923739-efa2-4791-bcc2-e24a457f5404", - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "\n", - "requests: dict[str, tuple[str, list[int], torch.Tensor]] = dict(\n", - " positive=[],\n", - " negative=[],\n", - ")\n", - "\n", - "def get_lp(type, prompt):\n", - " def processor(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - " ):\n", - " assert len(previously_generated_tokens) == 0\n", - " \n", - " requests[type].append(\n", - " (prompt, previously_generated_tokens, next_token_logits.cpu())\n", - " )\n", - "\n", - " return next_token_logits\n", - "\n", - " return processor\n", - "\n", - "def reset_requests():\n", - " global requests\n", - " requests = dict(\n", - " positive=[],\n", - " negative=[],\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "34d4881b-feee-4489-af94-4ab813db9f87", - "metadata": {}, - "source": [ - "## Run all examples" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "1489df89-28b4-418c-86e8-75eec5f6248c", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "16aef754794449e89dd2d76ee046c4e9", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/90000 [00:00= max_len:\n", - " break\n", - " \n", - " key = \"positive\" if row[\"use_function\"] else \"negative\"\n", - " prompt_token_ids = row[\"prompt_token_ids\"]\n", - " prompt = row[\"prompt\"]\n", - " \n", - " logits_processors = [\n", - " get_lp(key, prompt),\n", - " ]\n", - " \n", - " pending.append(\n", - " generate_no_wait(prompt_token_ids, logits_processors=logits_processors, max_tokens=1)\n", - " )\n", - "\n", - "completed = asyncio.as_completed(pending)\n", - "\n", - "for future in tqdm(completed, total=max_len):\n", - " await future" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "a52419c4-95c1-447f-be19-b7d7f6dcefe4", - "metadata": {}, - "outputs": [], - "source": [ - "import pickle\n", - "\n", - "# open a file, where you ant to store the data\n", - "with open('./processed_new.pickle', 'wb') as processed_file:\n", - "\n", - " # dump information to that file\n", - " pickle.dump(requests, processed_file)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c348f39-9735-4887-9e90-a748a2c3e278", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/model-serving/notebooks/process_dataset-Copy2.ipynb b/model-serving/notebooks/process_dataset-Copy2.ipynb deleted file mode 100644 index f84159356..000000000 --- a/model-serving/notebooks/process_dataset-Copy2.ipynb +++ /dev/null @@ -1,726 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "80aa2ec0-bc54-478f-96a8-746c7b1be871", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"] = '0,1'" - ] - }, - { - "cell_type": "markdown", - "id": "3ec2cf2f-2041-4cd8-accc-759686c7a65f", - "metadata": {}, - "source": [ - "## Sample Functions (generated by gpt4)\n", - "> [ChatGPT Thread](https://chat.openai.com/share/6ed2d0bb-ec35-4273-85b8-113d37db7f43)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f2498009-32ec-4cfa-8853-2d762d69ae44", - "metadata": {}, - "outputs": [], - "source": [ - "sample_functions = dict(\n", - " personal_trainer={ \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } },\n", - " budget_assistant={\n", - " \"name\": \"categorizeTransaction\",\n", - " \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"transactionDescription\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " home_agent={\n", - " \"name\": \"adjustThermostat\",\n", - " \"description\": \"Adjusts the home's thermostat to the desired temperature and mode.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"temperature\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"mode\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner={\n", - " \"name\": \"fetchRecipes\",\n", - " \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dietaryPreferences\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"availableIngredients\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " educational_tutor={\n", - " \"name\": \"generatePersonalizedQuiz\",\n", - " \"description\": \"Creates a quiz tailored to the user's learning level and performance history in a specific subject.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"UserID\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"Subject\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"DifficultyLevel\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner={\n", - " \"name\": \"searchFlights\",\n", - " \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"destination\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"departureDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"returnDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"budget\": {\n", - " \"type\": \"number\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner_2={\n", - " \"name\": \"findRecipesBasedOnIngredients\",\n", - " \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"ingredients\": {\n", - " \"type\": \"array\",\n", - " \"items\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner_2={\n", - " \"name\": \"findBestFlight\",\n", - " \"description\": \"Finds the best flight options based on user preferences.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"options\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dates\": {\"type\": \"string\"},\n", - " \"destinations\": {\"type\": \"string\"},\n", - " \"budget\": {\"type\": \"number\"}\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " health_monitor={\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " ecommerce_assistant={\n", - " \"name\": \"findProduct\",\n", - " \"description\": \"Searches for products based on a user's query and optional filters.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"query\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"filters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"priceRange\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"category\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e3eb2fd-49c9-49e2-8406-bff4fc7b7f62", - "metadata": {}, - "source": [ - "## Process dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "41efaf92-9ae2-4756-a894-40dcd04c48cb", - "metadata": {}, - "outputs": [], - "source": [ - "from datasets import load_dataset\n", - "\n", - "ds = load_dataset(\"togethercomputer/glaive-function-calling-v2-formatted\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "baed17a9-747b-4188-8644-05f850e3f725", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.remove_columns(\"text\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "47eae24a-648d-4efe-934d-40010a45ec3f", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import random\n", - "\n", - "def convert_tools_to_functions(row):\n", - " tools = json.loads(row[\"tools\"])\n", - "\n", - " # Get functions\n", - " functions = (\n", - " # [tool[\"function\"] for tool in tools]\n", - " # if tools else\n", - " random.sample(list(sample_functions.values()), 1)\n", - " )\n", - "\n", - " return dict(\n", - " functions='[]', # json.dumps(functions), # hf datasets cant hold arbitrary types\n", - " use_function=False\n", - " )\n", - "\n", - "ds = ds.map(convert_tools_to_functions).remove_columns(\"tools\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "3f61f791-c44d-4165-bf5f-1abbc10e5ef1", - "metadata": {}, - "outputs": [], - "source": [ - "def replace_system_message(row):\n", - " situation_content = \"You are a helpful assistant with access to one or more tools. Use them only if required to fulfill a user's request.\"\n", - " messages = json.loads(row[\"messages\"])\n", - "\n", - " # Sanity check\n", - " assert messages[0][\"role\"] == \"system\"\n", - " \n", - " # Replace system message\n", - " messages[0] = dict(\n", - " role=\"system\",\n", - " name=\"situation\",\n", - " content=situation_content,\n", - " )\n", - "\n", - " return dict(\n", - " messages=messages[:2], # Only keep system and user messages\n", - " )\n", - "\n", - "ds = ds.map(replace_system_message)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "66e65bb5-da29-4808-87b6-cc9e503284bd", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.filter(lambda row: all(msg[\"content\"] for msg in row[\"messages\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "d3312b84-46f8-4c90-b8df-27582d986a3e", - "metadata": {}, - "outputs": [], - "source": [ - "from model_api.conversion.conversions import to_prompt, parse_message\n", - "from model_api.conversion.datatypes import ChatMLMessage\n", - "from model_api.protocol import FunctionDef\n", - "\n", - "# Convert to prompts\n", - "convert_to_prompt = lambda row: dict(\n", - " prompt=to_prompt(\n", - " messages=[\n", - " ChatMLMessage(**message)\n", - " for message in row[\"messages\"]\n", - " ],\n", - " functions=[\n", - " FunctionDef(**fn)\n", - " for fn in json.loads(row[\"functions\"])\n", - " ],\n", - " )\n", - ")\n", - "\n", - "ds = ds.map(convert_to_prompt)" - ] - }, - { - "cell_type": "markdown", - "id": "84e41df0-9095-402c-8e1b-b0ecc8f7748c", - "metadata": {}, - "source": [ - "## Start engine" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "174aa0cc-8697-44c0-a8dc-d5beb7ad39d0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AsyncEngineArgs(model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode='auto', trust_remote_code=False, download_dir=None, load_format='auto', dtype='bfloat16', kv_cache_dtype='auto', seed=0, max_model_len=None, worker_use_ray=False, pipeline_parallel_size=1, tensor_parallel_size=2, max_parallel_loading_workers=None, block_size=16, swap_space=4, gpu_memory_utilization=0.98, max_num_batched_tokens=None, max_num_seqs=256, max_paddings=256, disable_log_stats=False, revision=None, tokenizer_revision=None, quantization=None, enforce_eager=False, max_context_len_to_capture=8192, disable_custom_all_reduce=False, enable_lora=False, max_loras=1, max_lora_rank=16, lora_extra_vocab_size=256, max_cpu_loras=None, engine_use_ray=False, disable_log_requests=False, max_log_len=None)" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo\",\n", - " dtype=\"bfloat16\",\n", - " enforce_eager=False,\n", - " tensor_parallel_size=2,\n", - " swap_space=4, # GiB\n", - " gpu_memory_utilization=0.98,\n", - " max_num_seqs=256,\n", - ")\n", - "\n", - "\n", - "engine_args" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "28cee360-ef57-4610-85a9-21b4981c8d0a", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-02-20 15:57:03,178\tINFO worker.py:1724 -- Started a local Ray instance.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 15:57:04 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=32768, download_dir=None, load_format=auto, tensor_parallel_size=2, disable_custom_all_reduce=False, quantization=None, enforce_eager=False, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-20 15:57:10 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:10 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "INFO 02-20 15:57:12 weight_utils.py:164] Using model weights format ['*.bin']\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:12 weight_utils.py:164] Using model weights format ['*.bin']\n", - "INFO 02-20 15:57:29 llm_engine.py:322] # GPU blocks: 5169, # CPU blocks: 4096\n", - "INFO 02-20 15:57:30 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "INFO 02-20 15:57:30 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:30 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:30 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "INFO 02-20 15:57:37 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "INFO 02-20 15:57:37 model_runner.py:698] Graph capturing finished in 7 secs.\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:37 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "\u001b[36m(RayWorkerVllm pid=289234)\u001b[0m INFO 02-20 15:57:37 model_runner.py:698] Graph capturing finished in 7 secs.\n" - ] - } - ], - "source": [ - "engine = AsyncLLMEngine.from_engine_args(engine_args)" - ] - }, - { - "cell_type": "markdown", - "id": "20fa04bf-8121-4262-a8e4-e8f3aed05153", - "metadata": {}, - "source": [ - "## Tokenize prompt" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "fcbaba94-bcb3-4c81-976c-7051200fbb13", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "43a3c8b9bf5b4debbda6c0b2ed70a2d7", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Map: 0%| | 0/111944 [00:00= max_len:\n", - " break\n", - " \n", - " key = \"positive\" if row[\"use_function\"] else \"negative\"\n", - " prompt_token_ids = row[\"prompt_token_ids\"]\n", - " prompt = row[\"prompt\"]\n", - " \n", - " logits_processors = [\n", - " get_lp(key, prompt),\n", - " ]\n", - " \n", - " pending.append(\n", - " generate_no_wait(prompt_token_ids, logits_processors=logits_processors, max_tokens=1)\n", - " )\n", - "\n", - "completed = asyncio.as_completed(pending)\n", - "\n", - "for future in tqdm(completed, total=max_len):\n", - " await future" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "a52419c4-95c1-447f-be19-b7d7f6dcefe4", - "metadata": {}, - "outputs": [], - "source": [ - "import pickle\n", - "\n", - "# open a file, where you ant to store the data\n", - "with open('./processed_new_new.pickle', 'wb') as processed_file:\n", - "\n", - " # dump information to that file\n", - " pickle.dump(requests, processed_file)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2c348f39-9735-4887-9e90-a748a2c3e278", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/model-serving/notebooks/process_dataset.ipynb b/model-serving/notebooks/process_dataset.ipynb deleted file mode 100644 index 976be493a..000000000 --- a/model-serving/notebooks/process_dataset.ipynb +++ /dev/null @@ -1,731 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "80aa2ec0-bc54-478f-96a8-746c7b1be871", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"] = '0,1'" - ] - }, - { - "cell_type": "markdown", - "id": "3ec2cf2f-2041-4cd8-accc-759686c7a65f", - "metadata": {}, - "source": [ - "## Sample Functions (generated by gpt4)\n", - "> [ChatGPT Thread](https://chat.openai.com/share/6ed2d0bb-ec35-4273-85b8-113d37db7f43)" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "f2498009-32ec-4cfa-8853-2d762d69ae44", - "metadata": {}, - "outputs": [], - "source": [ - "sample_functions = dict(\n", - " personal_trainer={ \"name\": \"logWeight\", \"description\": \"Logs the users weight and provides a visual representation of their weight change over time.\", \"parameters\": { \"type\": \"object\", \"properties\": { \"weight\": { \"type\": \"number\" }, \"date\": { \"type\": \"string\", \"format\": \"date\" }, \"notes\": { \"type\": \"string\" } } } },\n", - " budget_assistant={\n", - " \"name\": \"categorizeTransaction\",\n", - " \"description\": \"This function categorizes transactions into budget categories based on the description provided.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"transactionDescription\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " home_agent={\n", - " \"name\": \"adjustThermostat\",\n", - " \"description\": \"Adjusts the home's thermostat to the desired temperature and mode.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"temperature\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"mode\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner={\n", - " \"name\": \"fetchRecipes\",\n", - " \"description\": \"Search for recipes based on dietary preferences and available ingredients.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dietaryPreferences\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"availableIngredients\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " educational_tutor={\n", - " \"name\": \"generatePersonalizedQuiz\",\n", - " \"description\": \"Creates a quiz tailored to the user's learning level and performance history in a specific subject.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"UserID\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"Subject\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"DifficultyLevel\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner={\n", - " \"name\": \"searchFlights\",\n", - " \"description\": \"Searches for flights based on provided criteria (destination, departure date, return date, and budget).\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"destination\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"departureDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"returnDate\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"budget\": {\n", - " \"type\": \"number\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " meal_planner_2={\n", - " \"name\": \"findRecipesBasedOnIngredients\",\n", - " \"description\": \"Searches a recipe database for recipes that can be made with a specific set of ingredients provided by the user.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"ingredients\": {\n", - " \"type\": \"array\",\n", - " \"items\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " travel_planner_2={\n", - " \"name\": \"findBestFlight\",\n", - " \"description\": \"Finds the best flight options based on user preferences.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"options\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"dates\": {\"type\": \"string\"},\n", - " \"destinations\": {\"type\": \"string\"},\n", - " \"budget\": {\"type\": \"number\"}\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - " health_monitor={\n", - " \"name\": \"logHealthMetric\",\n", - " \"description\": \"Logs various health metrics such as steps taken, heart rate, or sleep quality, along with the exact time of recording.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"metricName\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"value\": {\n", - " \"type\": \"number\"\n", - " },\n", - " \"timestamp\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " },\n", - " ecommerce_assistant={\n", - " \"name\": \"findProduct\",\n", - " \"description\": \"Searches for products based on a user's query and optional filters.\",\n", - " \"parameters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"query\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"filters\": {\n", - " \"type\": \"object\",\n", - " \"properties\": {\n", - " \"priceRange\": {\n", - " \"type\": \"string\"\n", - " },\n", - " \"category\": {\n", - " \"type\": \"string\"\n", - " }\n", - " }\n", - " }\n", - " }\n", - " }\n", - " },\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e3eb2fd-49c9-49e2-8406-bff4fc7b7f62", - "metadata": {}, - "source": [ - "## Process dataset" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "41efaf92-9ae2-4756-a894-40dcd04c48cb", - "metadata": {}, - "outputs": [], - "source": [ - "from datasets import load_dataset\n", - "\n", - "ds = load_dataset(\"togethercomputer/glaive-function-calling-v2-formatted\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "baed17a9-747b-4188-8644-05f850e3f725", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.remove_columns(\"text\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "47eae24a-648d-4efe-934d-40010a45ec3f", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "import random\n", - "\n", - "def convert_tools_to_functions(row):\n", - " tools = json.loads(row[\"tools\"])\n", - "\n", - " # Get functions\n", - " functions = (\n", - " [tool[\"function\"] for tool in tools]\n", - " if tools else\n", - " random.sample(list(sample_functions.values()), 2)\n", - " )\n", - "\n", - " return dict(\n", - " functions=json.dumps(functions), # hf datasets cant hold arbitrary types\n", - " use_function=not (not tools)\n", - " )\n", - "\n", - "ds = ds.map(convert_tools_to_functions).remove_columns(\"tools\")" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "3f61f791-c44d-4165-bf5f-1abbc10e5ef1", - "metadata": {}, - "outputs": [], - "source": [ - "def replace_system_message(row):\n", - " situation_content = \"You are a helpful assistant with access to one or more tools. Use them only if required to fulfill a user's request.\"\n", - " messages = json.loads(row[\"messages\"])\n", - "\n", - " # Sanity check\n", - " assert messages[0][\"role\"] == \"system\"\n", - " \n", - " # Replace system message\n", - " messages[0] = dict(\n", - " role=\"system\",\n", - " name=\"situation\",\n", - " content=situation_content,\n", - " )\n", - "\n", - " return dict(\n", - " messages=messages,\n", - " )\n", - "\n", - "ds = ds.map(replace_system_message)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "8b80c5dd-5af1-4449-adda-93b3bf1fe558", - "metadata": {}, - "outputs": [], - "source": [ - "def skip_last_asst_msg(row):\n", - " messages = row[\"messages\"]\n", - "\n", - " # If last message.role == \"assistant\", remove\n", - " if messages[-1][\"role\"] == \"assistant\":\n", - " messages.pop()\n", - "\n", - " return dict(\n", - " messages=messages,\n", - " )\n", - "\n", - "\n", - "ds = ds.map(skip_last_asst_msg)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "66e65bb5-da29-4808-87b6-cc9e503284bd", - "metadata": {}, - "outputs": [], - "source": [ - "ds = ds.filter(lambda row: all(msg[\"content\"] for msg in row[\"messages\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "d3312b84-46f8-4c90-b8df-27582d986a3e", - "metadata": {}, - "outputs": [], - "source": [ - "from model_api.conversion.conversions import to_prompt, parse_message\n", - "from model_api.conversion.datatypes import ChatMLMessage\n", - "\n", - "# Convert to prompts\n", - "convert_to_prompt = lambda row: dict(\n", - " prompt=to_prompt(\n", - " messages=[\n", - " ChatMLMessage(**message)\n", - " for message in row[\"messages\"]\n", - " ],\n", - " functions=json.loads(row[\"functions\"]),\n", - " )\n", - ")\n", - "\n", - "ds = ds.map(convert_to_prompt)" - ] - }, - { - "cell_type": "markdown", - "id": "84e41df0-9095-402c-8e1b-b0ecc8f7748c", - "metadata": {}, - "source": [ - "## Start engine" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "174aa0cc-8697-44c0-a8dc-d5beb7ad39d0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "AsyncEngineArgs(model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode='auto', trust_remote_code=False, download_dir=None, load_format='auto', dtype='bfloat16', kv_cache_dtype='auto', seed=0, max_model_len=None, worker_use_ray=False, pipeline_parallel_size=1, tensor_parallel_size=2, max_parallel_loading_workers=None, block_size=16, swap_space=4, gpu_memory_utilization=0.96, max_num_batched_tokens=None, max_num_seqs=512, max_paddings=256, disable_log_stats=False, revision=None, tokenizer_revision=None, quantization=None, enforce_eager=False, max_context_len_to_capture=8192, disable_custom_all_reduce=False, enable_lora=False, max_loras=1, max_lora_rank=16, lora_extra_vocab_size=256, max_cpu_loras=None, engine_use_ray=False, disable_log_requests=False, max_log_len=None)" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from vllm import AsyncLLMEngine, AsyncEngineArgs\n", - "\n", - "engine_args = AsyncEngineArgs(\n", - " model=\"julep-ai/samantha-1-turbo\",\n", - " dtype=\"bfloat16\",\n", - " enforce_eager=False,\n", - " tensor_parallel_size=2,\n", - " swap_space=4, # GiB\n", - " gpu_memory_utilization=0.96,\n", - " max_num_seqs=512,\n", - ")\n", - "\n", - "\n", - "engine_args" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "28cee360-ef57-4610-85a9-21b4981c8d0a", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-02-15 22:51:47,208\tINFO worker.py:1724 -- Started a local Ray instance.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-15 22:51:48 llm_engine.py:72] Initializing an LLM engine with config: model='julep-ai/samantha-1-turbo', tokenizer='julep-ai/samantha-1-turbo', tokenizer_mode=auto, revision=None, tokenizer_revision=None, trust_remote_code=False, dtype=torch.bfloat16, max_seq_len=32768, download_dir=None, load_format=auto, tensor_parallel_size=2, disable_custom_all_reduce=False, quantization=None, enforce_eager=False, kv_cache_dtype=auto, seed=0)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO 02-15 22:51:54 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:51:54 custom_all_reduce.py:125] NVLink detection failed with message \"Not Supported\". This is normal if your machine has no NVLink equipped\n", - "INFO 02-15 22:51:55 weight_utils.py:164] Using model weights format ['*.bin']\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:51:57 weight_utils.py:164] Using model weights format ['*.bin']\n", - "INFO 02-15 22:52:12 llm_engine.py:322] # GPU blocks: 4829, # CPU blocks: 4096\n", - "INFO 02-15 22:52:13 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "INFO 02-15 22:52:13 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:52:13 model_runner.py:632] Capturing the model for CUDA graphs. This may lead to unexpected consequences if the model is not static. To run the model in eager mode, set 'enforce_eager=True' or use '--enforce-eager' in the CLI.\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:52:13 model_runner.py:636] CUDA graphs can take additional 1~3 GiB memory per GPU. If you are running out of memory, consider decreasing `gpu_memory_utilization` or enforcing eager mode. You can also reduce the `max_num_seqs` as needed to decrease memory usage.\n", - "INFO 02-15 22:52:20 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "INFO 02-15 22:52:20 model_runner.py:698] Graph capturing finished in 7 secs.\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:52:20 custom_all_reduce.py:199] Registering 2275 cuda graph addresses\n", - "\u001b[36m(RayWorkerVllm pid=833042)\u001b[0m INFO 02-15 22:52:20 model_runner.py:698] Graph capturing finished in 7 secs.\n" - ] - } - ], - "source": [ - "engine = AsyncLLMEngine.from_engine_args(engine_args)" - ] - }, - { - "cell_type": "markdown", - "id": "20fa04bf-8121-4262-a8e4-e8f3aed05153", - "metadata": {}, - "source": [ - "## Tokenize prompt" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "fcbaba94-bcb3-4c81-976c-7051200fbb13", - "metadata": {}, - "outputs": [], - "source": [ - "tokenizer = engine.engine.tokenizer.tokenizer\n", - "\n", - "ds = ds.map(\n", - " lambda row: dict(\n", - " prompt_token_ids=tokenizer.encode(row[\"prompt\"])\n", - " )\n", - ")\n", - "\n", - "# )[\"train\"][0][\"prompt_token_ids\"]" - ] - }, - { - "cell_type": "markdown", - "id": "b53a215c-edef-407f-a31a-6af425dac9cb", - "metadata": {}, - "source": [ - "## Prepare generator" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "a91773a5-a70f-488e-ad28-fc8223e80a57", - "metadata": {}, - "outputs": [], - "source": [ - "from uuid import uuid4\n", - "from vllm.sampling_params import SamplingParams\n", - "\n", - "def prep_generator(\n", - " prompt_token_ids,\n", - " temperature=0,\n", - " max_tokens=1,\n", - " logits_processors=[],\n", - " **sampling_kwargs,\n", - "):\n", - " sampling_params = SamplingParams(\n", - " temperature=temperature,\n", - " max_tokens=max_tokens,\n", - " logits_processors=logits_processors,\n", - " **sampling_kwargs,\n", - " )\n", - " \n", - " res_generator = engine.generate(\n", - " sampling_params=sampling_params,\n", - " request_id=uuid4(),\n", - " prompt=None,\n", - " prompt_token_ids=prompt_token_ids,\n", - " )\n", - "\n", - " return res_generator\n", - "\n", - "async def generate(\n", - " prompt_token_ids,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt_token_ids, **sampling_kwargs)\n", - " final_res = None\n", - "\n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res\n", - "\n", - "def generate_no_wait(\n", - " prompt_token_ids,\n", - " **sampling_kwargs,\n", - "):\n", - " res_generator = prep_generator(prompt_token_ids, **sampling_kwargs)\n", - "\n", - " async def waiter():\n", - " final_res = None\n", - " \n", - " async for res in res_generator:\n", - " final_res = res\n", - " \n", - " return final_res\n", - "\n", - " return waiter()" - ] - }, - { - "cell_type": "markdown", - "id": "c0248caf-b8a7-4cf2-80d4-e92e6396a39c", - "metadata": {}, - "source": [ - "## Prep logits processor" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "024b08d7-c0a1-4e22-99ff-038a65056b83", - "metadata": {}, - "outputs": [], - "source": [ - "# List of tags \n", - "allowed_tags = [\"me\", \"function_call\", \"thought\"]\n", - "disallowed_tags = [\"situation\", \"person\", \"functions\", \"information\"]\n", - "tags = allowed_tags + disallowed_tags\n", - "\n", - "allowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in allowed_tags\n", - "]\n", - "\n", - "disallowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in disallowed_tags\n", - "]\n", - "\n", - "tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in tags\n", - "]\n", - "\n", - "tag_id_map = {\n", - " tag: tag_ids[0]\n", - " for tag, tag_ids in zip(tags, tag_token_ids)\n", - "}\n", - "\n", - "id_tag_map = {\n", - " id: tag\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "cd923739-efa2-4791-bcc2-e24a457f5404", - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "\n", - "requests: dict[str, tuple[str, list[int], torch.Tensor]] = dict(\n", - " positive=[],\n", - " negative=[],\n", - ")\n", - "\n", - "def get_lp(type, prompt):\n", - " def processor(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - " ):\n", - " assert len(previously_generated_tokens) == 0\n", - " \n", - " requests[type].append(\n", - " (prompt, previously_generated_tokens, next_token_logits.cpu())\n", - " )\n", - "\n", - " return next_token_logits\n", - "\n", - " return processor\n", - "\n", - "def reset_requests():\n", - " global requests\n", - " requests = dict(\n", - " positive=[],\n", - " negative=[],\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "14062cd7-e5e2-4352-b1d7-f47c5fa1e058", - "metadata": {}, - "outputs": [], - "source": [ - "def drop_disallowed_tokens(\n", - " previously_generated_tokens,\n", - " next_token_logits,\n", - "):\n", - " assert len(previously_generated_tokens) == 0\n", - "\n", - " next_token_logits_copy = next_token_logits.cpu().clone()\n", - " \n", - " # Creating a mask that is True for all elements except those at token indices of allowed\n", - " mask = torch.ones_like(next_token_logits_copy, dtype=torch.bool)\n", - " for token_id in allowed_tag_token_ids:\n", - " # Only unmask the first token\n", - " mask[token_id[0]] = False\n", - "\n", - " # Setting all except allowed to min value\n", - " min_logit = min(next_token_logits)\n", - " next_token_logits_copy[mask] = min_logit\n", - "\n", - " return next_token_logits_copy" - ] - }, - { - "cell_type": "markdown", - "id": "34d4881b-feee-4489-af94-4ab813db9f87", - "metadata": {}, - "source": [ - "## Run all examples" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "1489df89-28b4-418c-86e8-75eec5f6248c", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "bedd7cda63f94f638449cd4c3a162dd7", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/111943 [00:00\n", - "
\n", - " Figure\n", - "
\n", - " \n", - " \n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "03448551-c34d-4c0d-984e-1f094137652e", - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "7ffc9fbf-7d04-4688-985c-d001be019314", - "metadata": {}, - "outputs": [], - "source": [ - "# Get data points and labels\n", - "def get_training_points(select_tags, limit=-1):\n", - " data = []\n", - " labels = []\n", - "\n", - " for label, type in enumerate([\"negative\", \"positive\"]):\n", - " samples = requests[type][:limit]\n", - "\n", - " for sample in samples:\n", - " logit_tensor = sample[2]\n", - " \n", - " if select_tags:\n", - " logit_tensor = logit_tensor[[\n", - " tag_id_map[tag]\n", - " for tag in select_tags\n", - " ]]\n", - "\n", - " data.append(logit_tensor.to(torch.float16).numpy())\n", - " labels.append(label)\n", - "\n", - " return data, labels" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "f898b898-0490-424c-8b77-65d8c5c66975", - "metadata": {}, - "outputs": [], - "source": [ - "data, labels = get_training_points(tags) # None, limit=1000) # tags) #[\"me\", \"function_call\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "9d20d522-b29e-4f51-b2e6-6771a6fcccfa", - "metadata": {}, - "outputs": [], - "source": [ - "from imblearn.over_sampling import SMOTE, ADASYN\n", - "from imblearn.combine import SMOTEENN\n", - "from sklearn.model_selection import train_test_split\n", - "\n", - "# Assuming 'data' is your features and 'labels' are the true labels\n", - "_X_train, X_test, _y_train, y_test = train_test_split(\n", - " data,\n", - " labels,\n", - " stratify=labels,\n", - " test_size=0.3,\n", - " random_state=56,\n", - ")\n", - "\n", - "X_train, y_train = SMOTEENN(random_state=56).fit_resample(_X_train, _y_train)" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "8872d216-b412-4c66-bbb5-d12ebd91cf5f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(96017, 93901)" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "len([z for z in y_train if z]), len([z for z in y_train if not z])" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "371277cb-8152-4b2f-9604-11743d2c3f96", - "metadata": {}, - "outputs": [], - "source": [ - "from sklearn.ensemble import HistGradientBoostingClassifier\n", - "import numpy as np\n", - "import torch\n", - "\n", - "def train_gradient_boosted_trees(data, labels, **kwargs):\n", - " # Convert the list of tensors to a numpy array\n", - " X = np.vstack(data)\n", - "\n", - " # Convert the list of labels to a numpy array\n", - " y = np.array(labels)\n", - "\n", - " # Initialize the gradient-boosted trees model\n", - " model = HistGradientBoostingClassifier(**kwargs)\n", - "\n", - " # Train the model\n", - " model.fit(X, y)\n", - "\n", - " return model" - ] - }, - { - "cell_type": "code", - "execution_count": 125, - "id": "9609b292-8ebf-4e87-b0b9-7c1a902b67eb", - "metadata": {}, - "outputs": [], - "source": [ - "from tqdm.notebook import tqdm\n", - "model = train_gradient_boosted_trees(X_train, y_train, random_state=56, l2_regularization=0.25, max_iter=1000, max_leaf_nodes=63, learning_rate=0.2)" - ] - }, - { - "cell_type": "code", - "execution_count": 126, - "id": "67b63a85-bff8-449a-bbc8-8ffd85621b8b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Accuracy: 0.9836209148318301\n", - "Precision: 0.9684654300168634\n", - "Recall: 0.9863460712752254\n", - "F1 Score: 0.9773239736226335\n", - "ROC-AUC Score: 0.9982623882327812\n" - ] - } - ], - "source": [ - "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score\n", - "\n", - "predictions = model.predict(X_test)\n", - "probabilities = model.predict_proba(X_test)[:, 1] # Assuming the positive class is at index 1\n", - "\n", - "# Evaluate the model\n", - "accuracy = accuracy_score(y_test, predictions)\n", - "precision = precision_score(y_test, predictions)\n", - "recall = recall_score(y_test, predictions)\n", - "f1 = f1_score(y_test, predictions)\n", - "roc_auc = roc_auc_score(y_test, probabilities)\n", - "\n", - "print(f\"Accuracy: {accuracy}\")\n", - "print(f\"Precision: {precision}\")\n", - "print(f\"Recall: {recall}\")\n", - "print(f\"F1 Score: {f1}\")\n", - "print(f\"ROC-AUC Score: {roc_auc}\")" - ] - }, - { - "cell_type": "code", - "execution_count": 127, - "id": "ebf023e8-dcd3-48af-bef1-b9a20d7e59dd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([0])" - ] - }, - "execution_count": 127, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "model.predict(np.array(range(7)).reshape(1, -1))\n", - "# model.predict" - ] - }, - { - "cell_type": "code", - "execution_count": 128, - "id": "d5772f77-6a7f-4826-afa1-33312c8c9c32", - "metadata": {}, - "outputs": [], - "source": [ - "with open(\"model.np\", \"wb\") as f:\n", - " pickle.dump(model, f)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f331b5d3-309f-499d-85f8-0b2d2c373a8a", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/model-serving/notebooks/visualize_dataset.ipynb b/model-serving/notebooks/visualize_dataset.ipynb deleted file mode 100644 index a845907d7..000000000 --- a/model-serving/notebooks/visualize_dataset.ipynb +++ /dev/null @@ -1,510 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "958d599e-9af1-4344-8c69-5e35e91d8336", - "metadata": {}, - "outputs": [], - "source": [ - "import pickle\n", - "\n", - "# open a file, where you ant to store the data\n", - "with open('./processed.pickle', 'rb') as processed_file:\n", - "\n", - " # dump information to that file\n", - " requests = pickle.load(processed_file)\n", - "\n", - "# open a file, where you ant to store the data\n", - "with open('./processed_new.pickle', 'rb') as processed_new_file:\n", - "\n", - " # dump information to that file\n", - " requests_new = pickle.load(processed_new_file)\n", - "\n", - "\n", - "# # open a file, where you ant to store the data\n", - "# with open('./processed_new_new.pickle', 'rb') as processed_new_new_file:\n", - "\n", - "# # dump information to that file\n", - "# requests_new_new = pickle.load(processed_new_new_file)\n", - "\n", - "\n", - "requests[\"positive\"] += requests_new[\"positive\"]\n", - "requests[\"negative\"] += requests_new[\"negative\"]\n", - "\n", - "# requests[\"positive\"] += requests_new_new[\"positive\"]\n", - "# requests[\"negative\"] += requests_new_new[\"negative\"]\n" - ] - }, - { - "cell_type": "markdown", - "id": "8421f8bd-ab08-40fb-87bd-3aacd5ee200f", - "metadata": {}, - "source": [ - "## Analyze tags" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "8dc59b5d-a5c8-4b51-a91d-aadd21516f8b", - "metadata": {}, - "outputs": [], - "source": [ - "from torch.nn import functional as F\n", - "\n", - "def get_dist(type, idx, upper=50, lower=-2, output_probs=False):\n", - " if output_probs:\n", - " values = F.softmax(requests[type][idx][2], dim=-1)\n", - " else:\n", - " values = requests[type][idx][2]\n", - " \n", - " values = values.tolist()\n", - " \n", - " return [min(upper, max(lower, v)) for v in values]" - ] - }, - { - "cell_type": "markdown", - "id": "f8292ea9-df95-47dd-bcd3-911123bda6de", - "metadata": {}, - "source": [ - "## Visualize" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "af66c128-2dde-4ea2-b7e5-14af3968399f", - "metadata": {}, - "outputs": [], - "source": [ - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "from mplcursors import cursor\n", - "\n", - "# Plotting\n", - "def plot(type, idx, output_probs=False):\n", - " dist = get_dist(type, idx, output_probs=output_probs)\n", - "\n", - " plt.clf()\n", - " plt.figure(figsize=(15, 6))\n", - " plt.plot(dist, marker='o', linestyle='-', color='blue')\n", - " plt.title(f'Plot of result {idx}')\n", - " plt.xlabel('Index')\n", - " plt.ylabel('Logit')\n", - " \n", - " # Highlighting tags\n", - " # b : blue · g : green · r : red · c : cyan · m : magenta · y : yellow · k : black\n", - " colors = \"b,g,r,c,m,y,k\".split(',')\n", - " \n", - " for (tag, id), color in zip(tag_id_map.items(), colors):\n", - " plt.axvline(x=id, color=color, linestyle='--', label=tag) # Indices are 0-based\n", - "\n", - " # Dotted horizontal line on zero\n", - " plt.axhline(y=0, color='y', linestyle=':', label='y=0 Line')\n", - "\n", - " plt.legend()\n", - " cursor(hover=True)\n", - "\n", - " plt.show()\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5b88522c-456d-430b-94dc-cc61a913047c", - "metadata": {}, - "outputs": [], - "source": [ - "%matplotlib widget\n", - "show = lambda type, idx, output_probs=False: (requests[type][idx][0], plot(type, idx, output_probs))" - ] - }, - { - "cell_type": "markdown", - "id": "0798a8d3-8b17-4e5c-9c90-919bf16bda17", - "metadata": {}, - "source": [ - "### Positive samples\n", - "> (where a function should be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "7e972a94-0df8-4df1-b3e6-76c6df9495cf", - "metadata": {}, - "outputs": [], - "source": [ - "import ipywidgets as wg\n", - "\n", - "# wg.interact(show, type=\"positive\", idx=wg.IntSlider(min=0, max=len(requests[\"positive\"])-1, step=1))" - ] - }, - { - "cell_type": "markdown", - "id": "c84d7a4e-8f25-430b-8131-ed121d1b713d", - "metadata": {}, - "source": [ - "### Negative samples\n", - "> (where functions should NOT be called)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "21888f23-fb08-464a-a12e-f92f9bbac7a5", - "metadata": {}, - "outputs": [], - "source": [ - "# wg.interact(show, type=\"negative\", idx=wg.IntSlider(min=0, max=len(requests[\"negative\"])-1, step=1))" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "f24814cc-ecbf-428c-9be9-507a882d3f14", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n" - ] - } - ], - "source": [ - "from transformers import AutoTokenizer\n", - "\n", - "model_name = \"julep-ai/samantha-1-turbo\"\n", - "tokenizer = AutoTokenizer.from_pretrained(model_name)" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "0795d3ea-ac9c-4f82-861e-2a8cd173d3f4", - "metadata": {}, - "outputs": [], - "source": [ - "# List of tags \n", - "allowed_tags = [\"me\", \"function_call\", \"thought\"]\n", - "disallowed_tags = [\"situation\", \"person\", \"functions\", \"information\"]\n", - "tags = allowed_tags + disallowed_tags\n", - "\n", - "allowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in allowed_tags\n", - "]\n", - "\n", - "disallowed_tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in disallowed_tags\n", - "]\n", - "\n", - "tag_token_ids = [\n", - " tokenizer(tag, add_special_tokens=False)[\"input_ids\"]\n", - " for tag in tags\n", - "]\n", - "\n", - "tag_id_map = {\n", - " tag: tag_ids[0]\n", - " for tag, tag_ids in zip(tags, tag_token_ids)\n", - "}\n", - "\n", - "id_tag_map = {\n", - " id: tag\n", - " for tag, id in tag_id_map.items()\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "bfee96d3-5343-47a4-ade6-4718caf1cbe4", - "metadata": {}, - "outputs": [], - "source": [ - "get_points = lambda type, select_tags, limit=-1: [\n", - " req[2].tolist()\n", - " if select_tags is None\n", - " else [\n", - " req[2][tag_id_map[tag]].item()\n", - " for tag in select_tags\n", - " ]\n", - " for req in requests[type][:limit]\n", - "]" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "541e5e0e-c9a4-4464-a635-da44496fac19", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", [\"me\", \"function_call\"])\n", - "negative_points = get_points(\"negative\", [\"me\", \"function_call\"])\n", - "\n", - "positive_xs, positive_ys = zip(*positive_points)\n", - "negative_xs, negative_ys = zip(*negative_points)\n", - "\n", - "xs = negative_xs + positive_xs\n", - "ys = negative_ys + positive_ys\n", - "colors = ['r']*len(negative_xs) + ['b']*len(positive_xs)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d4e8f9f0-3fed-432e-92cc-2389f33b23a8", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "b2d65126cd7e42a0931efdbdf628b475", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "plt.scatter(xs, ys, c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "f142efa1-dbcb-4bee-b78e-a4686b0e88ac", - "metadata": {}, - "source": [ - "## PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "bd0bd893-6201-4e4b-a254-c1f520de3221", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.decomposition import KernelPCA, PCA" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "cb764bc0-d2d3-490f-900c-540bdb201390", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", tags)\n", - "negative_points = get_points(\"negative\", tags)\n", - "\n", - "# p_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "# n_pca = KernelPCA(n_components=2, kernel=\"cosine\")\n", - "p_pca = PCA(n_components=3)\n", - "n_pca = PCA(n_components=3)\n", - "\n", - "positive_points_t = p_pca.fit_transform(np.array(positive_points))\n", - "negative_points_t = n_pca.fit_transform(np.array(negative_points))" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "e4f1dba6-aeb9-4f30-ae7c-0359c9c161f4", - "metadata": {}, - "outputs": [], - "source": [ - "positive_xs, positive_ys, positive_zs = zip(*positive_points_t)\n", - "negative_xs, negative_ys, negative_zs = zip(*negative_points_t)\n", - "\n", - "xs = negative_xs + positive_xs\n", - "ys = negative_ys + positive_ys\n", - "zs = negative_zs + positive_zs\n", - "colors = [[1,0,0,0.5]]*len(negative_xs) + [[0,0,1,0.5]]*len(positive_xs)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "c1a621bb-b164-4ff2-9389-802b944db4ee", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "258691ba2fa54dfd8ab5666020b8a614", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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msrMmTMDUnGtKAp//etfeeCBB9i+fTs33XST3x9jPB5//HGeffZZIiMjCQkJYeXKlTz11FNiAokgDBABUBAGGc+YOtWxY8dYsGABVVVV5OTkBOoSL2sej4d//OMfvPLKK+zcuZPe3l42bNhAYWEha9as8VtVrjqeTq/Xs3jx4lGt6g0eSWexWOjt7SU2NlYLg4EKqiPp7e3l0KFDAQ1/ANu3b+frX/86L7/8Mhs2bAjIY4zHm2++id1uJycnh+bmZp544gkaGxs5evTotJzYIgj+JgKgIPjJX/7yF+666y5sNhvR0dGTfTmXPK/Xy4EDB7SRdO3t7axbt47CwkJuuummcVdju91uSkpKCAoKuqjxdOpIOovFQk9PT0BH0g332BMR/nbt2sU999zDX/7yF4qKigLyGP7S2dlJRkYGzz33HPfee+9kX44gTDoRAAVhHA4cOMDBgwdZvXo1ZrOZAwcO8NBDD7F+/fphJ5cIgSXLMp988okWBpuamrjpppsoLCxk/fr1o17xcblcFBcXExoaysKFC/1W3DHcSDo1DPq7kbQa/lJSUoZMX/G3t956i7vuuos///nP3H777QF5DH9btmwZa9as4amnnprsSxGESScCoCCMQ0lJCf/0T/9EVVUVTqeTrKws7rzzTr797W+L83+TTJZlysvL2bp1K9u3b6euro4bbriBwsJCNmzYQGRk5LChyOl0UlxcTHh4OAsWLAhYZe9II+kSEhIuuofkRIW/3bt3c8cdd/CHP/yBz3/+85MyzWWs7HY76enpPP744zz44IOTfTmCMOlEABQE4ZKlTu7YunUrO3bsoKqqiuuuu46ioiI2btxITEwMkiRRU1PDiRMnmDFjBvPmzZuwti4jjaRLSEggPDx8TMGqt7eX4uJikpOTAxr+9u3bx+23386vf/1rtmzZMmXD3yOPPMKmTZvIyMigqamJH/3oR5SVlVFRUSEaUwsCIgAKgnCZUBSF48ePs23bNrZv3055eTlXX301V1xxBc8//zy33347zzzzzKQFmpFG0iUkJBAREXHe6+rr6+PQoUMkJSUxe/bsgH0M+/fv59Zbb+Vf//Vf+epXvzplwx/AHXfcwb59+2hrayM+Pp6rrrqKn/70pwFrhSMI040IgIIwDf37v/87zz77LC0tLSxatIhf//rXLF++fLIva9pQFIXa2lp+//vf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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.clf()\n", - "\n", - "fig = plt.figure()\n", - "ax = fig.add_subplot(projection='3d')\n", - "\n", - "ax.scatter(xs, ys, zs=zs, zdir='z', c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "f1529874-fbc7-4328-bb8d-0ea18c70e215", - "metadata": {}, - "source": [ - "## TSNE" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "67849c3d-0922-4c47-94b3-cb8ef6d4a812", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "from sklearn.manifold import TSNE" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "773decfd-ca04-4f86-9f53-f5c5edc7cc94", - "metadata": {}, - "outputs": [], - "source": [ - "positive_points = get_points(\"positive\", tags, limit=10_000)\n", - "negative_points = get_points(\"negative\", tags, limit=10_000)\n", - "\n", - "p_pca = TSNE(n_components=3, n_jobs=8)\n", - "n_pca = TSNE(n_components=3, n_jobs=8)\n", - "\n", - "positive_points_t = p_pca.fit_transform(np.array(positive_points))\n", - "negative_points_t = n_pca.fit_transform(np.array(negative_points))" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "16ff4553-aeaa-4ace-88e9-5fb215351195", - "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3e5ff9edf63b4fcba0ee68a84bad35d2", - "version_major": 2, - "version_minor": 0 - }, - "image/png": "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pK6ujoKCAmJiYqb8fJNhJsTfUKivqcVioauri0cffZTVq1dz8uRJrfI304bYQ/Gb3/yGn//857S2tpKbm8uvf/1r1q5dO9vH0tGZEXQBqBMUlJWV8c1vfpPS0lIcDgepqals2rSJH/zgB6Snp2u3628EnZiYyF133cW99947iyf/5KEoCidPnmTHjh3s2rWLjz/+mPXr17N161a2bNlCenr6lIhB9XFOnTo1Y5W1wXm6UVFRmr3MYCuU/ukohYWFREVFTfv5xsNsib/BOBwOnnjiCZ544glaW1tZtGgRN998M9dddx15eXmzNlLw/PPPs337dn7729+ybt06fvnLX/L3v/+dqqqqoNvc1tGZDnQBqPOJpK6ujgcffJC9e/fS2tpKWloat9xyC9///vcHtAD15JGRURSFhoYGdu7cya5duzhw4ACrV69m69atbN26lczMzAld4NWKY0tLCwUFBbMirjwejyYGOzo6BlihREREUFNTQ3Nz86zHpw1FsIg/8G9m/+AHP+DFF1/kH//4B1VVVezatYvXXnuNZ599luuvv35WzrVu3TrWrFnDY489pp0zIyODu+66i/vuu29WzqSjM5PoAlDnE8kbb7zB888/z2c+8xlycnI4evQot99+O5///Of5xS9+AejJI+NFURRaWlrYtWsXO3fu5N1332XVqlWaGMzJyRmTGFQUhYqKCjo6OigoKJhV8aKiWqG0t7djtVoRRRFFUVi2bNm0tr8nQjCJP0VR+PGPf8yf/vQn9u3bx5IlS7TPud1ugBlNHFHxeDyEh4fz4osvsm3bNu3jt956K11dXbz88sszfiYdnZlGF4A6OgF+/vOf88QTT1BbWwugJ49MAkVRsFqtvPTSS+zYsYO9e/eyZMkStm7dyrZt21iyZMmQokmWZY4ePUpvby+FhYVjmsGbSRRF4dixY1itVmJjY+ns7MRoNJKUlERKSsqsbkmr5wsm8ffTn/6UJ598kr1797JixYpZO8tgmpubSU9P1xwGVL773e+yf/9+Pvroo1k8nY7OzKD7AOroBOju7h5g3/HBBx9w0UUXDWgJX3nllVRVVdHZ2TkbRzxrEASBpKQkbr/9dl5//XVaW1v5zne+Q0lJCeeffz6rV6/mxz/+MWVlZciyDPg3c3ft2oXT6WTNmjVBK/66uro477zzyMvL4+KLL2bp0qXIskxp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", - "text/html": [ - "\n", - "
\n", - "
\n", - " Figure\n", - "
\n", - " \n", - "
\n", - " " - ], - "text/plain": [ - "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "positive_xs, positive_ys, positive_zs = zip(*positive_points_t)\n", - "negative_xs, negative_ys, negative_zs = zip(*negative_points_t)\n", - "\n", - "xs = negative_xs + positive_xs\n", - "ys = negative_ys + positive_ys\n", - "zs = negative_zs + positive_zs\n", - "colors = [[1,0,0,0.5]]*len(negative_xs) + [[0,0,1,0.5]]*len(positive_xs)\n", - "\n", - "plt.clf()\n", - "\n", - "fig = plt.figure()\n", - "ax = fig.add_subplot(projection='3d')\n", - "\n", - "ax.scatter(xs, ys, zs=zs, zdir='z', c=colors)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e59f38dc-01a9-4832-bf1c-f2e88c79b506", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}