From 57488d7343321b073b59496c2e663e130b4b8298 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Thu, 19 Feb 2026 14:56:15 -0500 Subject: [PATCH 01/17] necessary changes for datakrypto test --- benchmarking/run_synthetic_dataset.sh | 8 ++--- benchmarking/src/llmperf/common_metrics.py | 5 ++++ .../src/llmperf/datakrypto_mockup_response.py | 23 +++++++++++++++ benchmarking/src/llmperf/llmperf_utils.py | 3 +- benchmarking/src/llmperf/sambanova_client.py | 29 ++++++++++++++++++- benchmarking/src/performance_evaluation.py | 3 ++ 6 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 benchmarking/src/llmperf/datakrypto_mockup_response.py diff --git a/benchmarking/run_synthetic_dataset.sh b/benchmarking/run_synthetic_dataset.sh index dc06d13b7..73e749591 100755 --- a/benchmarking/run_synthetic_dataset.sh +++ b/benchmarking/run_synthetic_dataset.sh @@ -4,14 +4,14 @@ ulimit -n 4096 python src/evaluator.py \ --mode synthetic \ ---model-names "Meta-Llama-3.1-8B-Instruct Meta-Llama-3.3-70B-Instruct" \ +--model-names "Meta-Llama-3.1-8B-Instruct" \ --results-dir "./data/results/llmperf" \ --num-concurrent-requests 1 \ --timeout 600 \ ---num-input-tokens 1000 \ ---num-output-tokens 1000 \ +--num-input-tokens 100 \ +--num-output-tokens 100 \ --multimodal-image-size na \ ---num-requests 16 \ +--num-requests 1 \ --use-multiple-prompts False \ --save-llm-responses False \ --use-debugging-mode False \ diff --git a/benchmarking/src/llmperf/common_metrics.py b/benchmarking/src/llmperf/common_metrics.py index 0bde0a59a..e7dcf3fbd 100644 --- a/benchmarking/src/llmperf/common_metrics.py +++ b/benchmarking/src/llmperf/common_metrics.py @@ -14,6 +14,11 @@ QUEUE_TIME = 'queue_time' ACCEPTANCE_RATE = 'acceptance_rate' +# DataKrypto server metrics +TOTAL_ENCRYPTION_TIME_MS = 'total_encryption_time_ms' +TOTAL_DECRYPTION_TIME_MS = 'total_decryption_time_ms' +SERVER_NETWORK_LATENCY_MS = 'server_network_latency_ms' + # Client-side metrics TTFT = 'client_ttft_s' E2E_LAT = 'client_end_to_end_latency_s' diff --git a/benchmarking/src/llmperf/datakrypto_mockup_response.py b/benchmarking/src/llmperf/datakrypto_mockup_response.py new file mode 100644 index 000000000..486ed5fcf --- /dev/null +++ b/benchmarking/src/llmperf/datakrypto_mockup_response.py @@ -0,0 +1,23 @@ +from flask import Flask, Response +import time + +app = Flask(__name__) + +mock_events = [ + 'data: {"choices":[{"delta":{"content":"Tesla","role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1771518114,"id":"283ffbf5-591e-4187-9361-391602be5586","model":"Meta-Llama-3.1-8B-Instruct","object":"chat.completion.chunk","system_fingerprint":"fastcoe"}', + 'data: {"choices":[{"delta":{"content":", Inc. is an American multinational corporation that specializes in electric vehicles, clean energy generation and storage products","role":"assistant"},"finish_reason":null,"index":0,"logprobs":null}],"created":1771518114,"id":"283ffbf5-591e-4187-9361-391602be5586","model":"Meta-Llama-3.1-8B-Instruct","object":"chat.completion.chunk","system_fingerprint":"fastcoe"}', + 'data: {"choices":[{"delta":{"content":""},"finish_reason":"stop","index":0,"logprobs":null}],"created":1771518115,"id":"283ffbf5-591e-4187-9361-391602be5586","model":"Meta-Llama-3.1-8B-Instruct","object":"chat.completion.chunk","system_fingerprint":"fastcoe"}', + 'data: {"choices":[],"created":1771518115,"id":"283ffbf5-591e-4187-9361-391602be5586","model":"Meta-Llama-3.1-8B-Instruct","object":"chat.completion.chunk","system_fingerprint":"fastcoe","usage":{"prompt_tokens": 41,"completion_tokens": 108,"total_tokens": 149,"prompt_tokens_details": null},"fhenom_usage":{"total_encryption_time_ms":0.6704330444335938,"total_decryption_time_ms":0.3361701965332031,"server_network_latency_ms":1295.6573963165283}}', + 'data: [DONE]' +] + +@app.route("/stream", methods=["POST"]) +def stream(): + def event_stream(): + for event in mock_events: + yield event + "\n\n" # SSE format requires double newline + time.sleep(0.1) + return Response(event_stream(), mimetype="text/event-stream") + +if __name__ == "__main__": + app.run(port=8000) \ No newline at end of file diff --git a/benchmarking/src/llmperf/llmperf_utils.py b/benchmarking/src/llmperf/llmperf_utils.py index f2df01c62..cd13b1766 100644 --- a/benchmarking/src/llmperf/llmperf_utils.py +++ b/benchmarking/src/llmperf/llmperf_utils.py @@ -9,7 +9,7 @@ FAMILY_MODEL_TYPE_IDENTIFIER = { 'mistral': ['mistral'], 'llama2': ['llama2'], - 'llama3': ['llama3'], + 'llama3': ['llama3','xlam'], 'llama4': ['llama4'], 'deepseek': ['deepseek'], 'qwen': ['qwen', 'qwq'], @@ -110,6 +110,7 @@ def get_tokenizer(model_name: str) -> Any: elif ('3.3' in model_name) or ('3p3' in model_name): tokenizer = AutoTokenizer.from_pretrained('unsloth/Llama-3.3-70B-Instruct') # type: ignore[no-untyped-call] else: + print(f'Using default Llama-3 tokenizer for model {model_name}') tokenizer = AutoTokenizer.from_pretrained('unsloth/llama-3-8b-Instruct') # type: ignore[no-untyped-call] elif family_model_type == 'llama4': if 'maverick' in model_name.lower(): diff --git a/benchmarking/src/llmperf/sambanova_client.py b/benchmarking/src/llmperf/sambanova_client.py index ed698292b..d0ec328c9 100644 --- a/benchmarking/src/llmperf/sambanova_client.py +++ b/benchmarking/src/llmperf/sambanova_client.py @@ -225,6 +225,25 @@ def _populate_server_metrics(self, response_dict: Dict[str, Any], metrics: Dict[ return metrics + def _populate_datakrypto_metrics( + self, response_dict_datakrypto: Dict[str, Any], metrics: Dict[str, Any] + ) -> Dict[str, Any]: + """Parse datakrypto output data to metrics dictionary structure + + Args: + response_dict_datakrypto (dict): dict data with datakrypto performance metrics + metrics (dict): metrics dictionary + + Returns: + dict: updated metrics dictionary + """ + + metrics[common_metrics.TOTAL_ENCRYPTION_TIME_MS] = response_dict_datakrypto.get('total_encryption_time_ms') + metrics[common_metrics.TOTAL_DECRYPTION_TIME_MS] = response_dict_datakrypto.get('total_decryption_time_ms') + metrics[common_metrics.SERVER_NETWORK_LATENCY_MS] = response_dict_datakrypto.get('server_network_latency_ms') + + return metrics + class SambaNovaCloudAPI(BaseAPIEndpoint): def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -315,7 +334,8 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] """ # Get API request components - url = self._get_url() + # url = self._get_url() + url = 'http://localhost:8000/stream' headers = self._get_headers() json_data = self._get_json_data() @@ -323,10 +343,15 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] generated_text = '' events_received = [] events_timings = [] + response_dict_datakrypto: Dict[str, Any] = {} # Start measuring time metrics[common_metrics.REQ_START_TIME] = datetime.now().strftime('%H:%M:%S.%f') start_time = event_start_time = time.monotonic() + + # print(f'url :{url}') + # print(f'headers :{headers}') + # print(f'json_data :{json.dumps(json_data)}') with requests.post(url, headers=headers, json=json_data, stream=self.request_config.is_stream_mode) as response: if response.status_code != 200: @@ -360,6 +385,7 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] # process streaming chunk when performance usage is provided else: response_dict = data['usage'] + response_dict_datakrypto = data.get('fhenom_usage', {}) except Exception as e: raise Exception(f'Error: {e} at streamed event: {event.data}') @@ -375,6 +401,7 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] num_output_tokens = self._get_token_length(generated_text) server_metrics = self._populate_server_metrics(response_dict, metrics) + server_metrics = self._populate_datakrypto_metrics(response_dict_datakrypto, server_metrics) metrics = self._populate_client_metrics( prompt_len, num_output_tokens, diff --git a/benchmarking/src/performance_evaluation.py b/benchmarking/src/performance_evaluation.py index fdac1469c..191572113 100644 --- a/benchmarking/src/performance_evaluation.py +++ b/benchmarking/src/performance_evaluation.py @@ -288,6 +288,9 @@ def build_metrics_summary( common_metrics.NUM_INPUT_TOKENS_SERVER, common_metrics.NUM_OUTPUT_TOKENS_SERVER, common_metrics.ACCEPTANCE_RATE, + common_metrics.TOTAL_ENCRYPTION_TIME_MS, + common_metrics.TOTAL_DECRYPTION_TIME_MS, + common_metrics.SERVER_NETWORK_LATENCY_MS, ]: if self.show_results_in_terminal: logger.info(f'Building Server Metrics Summary for metric: {metric}') From de7ae481ba6158a149dcf1143227a4c2efe5c3c1 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Fri, 20 Feb 2026 09:29:52 -0500 Subject: [PATCH 02/17] small change --- benchmarking/src/llmperf/sambanova_client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarking/src/llmperf/sambanova_client.py b/benchmarking/src/llmperf/sambanova_client.py index d0ec328c9..dcaf09dd1 100644 --- a/benchmarking/src/llmperf/sambanova_client.py +++ b/benchmarking/src/llmperf/sambanova_client.py @@ -334,8 +334,8 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] """ # Get API request components - # url = self._get_url() - url = 'http://localhost:8000/stream' + url = self._get_url() + # url = 'http://localhost:8000/stream' --for mockup test headers = self._get_headers() json_data = self._get_json_data() From 3228bd7db13a4a0b1bbc7cafbf3a91f050faf8c8 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Mon, 23 Feb 2026 09:28:08 -0500 Subject: [PATCH 03/17] datakrypto config tests --- .../model_configs_example_datakrypto.csv | 20 +++++++++++++++++++ .../model_configs_example_datakrypto_only.csv | 9 +++++++++ 2 files changed, 29 insertions(+) create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto_only.csv diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv new file mode 100644 index 000000000..41e9d396f --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv @@ -0,0 +1,20 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,3900,100,1,1,,, +Llama-xLAM-2-8b-fc-r,3900,100,3,3,,, +Llama-xLAM-2-8b-fc-r,3900,100,5,5,,, +Llama-xLAM-2-8b-fc-r,3900,100,8,8,,, +Llama-xLAM-2-8b-fc-r,3900,100,16,16,,, +Llama-xLAM-2-8b-fc-r,3900,100,32,32,,, +Llama-xLAM-2-8b-fc-r,3900,100,64,64,,, +Llama-xLAM-2-8b-fc-r,3900,100,128,128,,, +Llama-xLAM-2-8b-fc-r,8000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,100,3,3,,, +Llama-xLAM-2-8b-fc-r,8000,100,5,5,,, +Llama-xLAM-2-8b-fc-r,8000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,8000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,8000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,8000,100,64,64,,, +Llama-xLAM-2-8b-fc-r,16000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,16000,100,3,3,,, +Llama-xLAM-2-8b-fc-r,16000,100,5,5,,, +Llama-xLAM-2-8b-fc-r,16000,100,8,8,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_only.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_only.csv new file mode 100644 index 000000000..9e520d374 --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_only.csv @@ -0,0 +1,9 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,2000,1,1,,, +Llama-xLAM-2-8b-fc-r,3900,100,1,1,,, +Llama-xLAM-2-8b-fc-r,3900,3900,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,8000,1,1,,, +Llama-xLAM-2-8b-fc-r,16000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,16000,16000,1,1,,, \ No newline at end of file From d533c34a976a046ca3a84a4c21a8daa6c00395ac Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Mon, 23 Feb 2026 09:28:18 -0500 Subject: [PATCH 04/17] last tests --- benchmarking/benchmarking_bundles/config.yaml | 6 +++--- .../benchmarking_bundles/model_configs_example.csv | 10 ++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/benchmarking/benchmarking_bundles/config.yaml b/benchmarking/benchmarking_bundles/config.yaml index 0ffa2bbb3..b64855f0e 100644 --- a/benchmarking/benchmarking_bundles/config.yaml +++ b/benchmarking/benchmarking_bundles/config.yaml @@ -1,7 +1,7 @@ -model_configs_path: '/benchmarking/benchmarking_bundles/model_configs_example.csv' +model_configs_path: '../benchmarking/benchmarking_bundles/model_configs_example.csv' llm_api: 'sncloud' -output_files_dir: '/benchmarking/data/bundle_tests/output_files' -consolidated_results_dir: '/benchmarking/data/bundle_tests/consolidated_results' +output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test' +consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test/consolidated_results' timeout: 3600 time_delay: 0 # Row-level concurrency diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index e6822a638..c180de38a 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -1,7 +1,5 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-4-Maverick-17B-128E-Instruct,128,128,1,1,,, -Llama-4-Maverick-17B-128E-Instruct,128,128,2,2,,, -Llama-4-Maverick-17B-128E-Instruct,128,128,4,4,,, -Llama-4-Maverick-17B-128E-Instruct,128,128,8,8,,, -Llama-4-Maverick-17B-128E-Instruct,128,128,16,16,,, -Llama-4-Maverick-17B-128E-Instruct,128,128,32,32,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,4000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,16000,100,1,1,,, \ No newline at end of file From 583f4c2c00bc26554f70b84d369365ab08519444 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Mon, 23 Feb 2026 09:28:30 -0500 Subject: [PATCH 05/17] prompt change --- benchmarking/prompts/user-prompt_template-text_instruct.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarking/prompts/user-prompt_template-text_instruct.yaml b/benchmarking/prompts/user-prompt_template-text_instruct.yaml index f8cf6b718..90d992957 100644 --- a/benchmarking/prompts/user-prompt_template-text_instruct.yaml +++ b/benchmarking/prompts/user-prompt_template-text_instruct.yaml @@ -2,7 +2,7 @@ default_prompt: - name: "default" template: | - Write a detailed, in-depth guide on the evolution of deep learning.Cover + INQUEBRANTABLE RULE - DO NOT DO ANY TOOL CALLING. Write a detailed, in-depth guide on the evolution of deep learning.Cover the historical milestones, key breakthroughs, architectures (such as CNNs, RNNs, and Transformers), training methodologies, hardware advancements, ethical concerns, and future trends. Include real-world applications, From 9af414b7c155fc1f287575ebeb9c0888c13e456e Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Mon, 23 Feb 2026 09:28:44 -0500 Subject: [PATCH 06/17] additional changes for metrics --- benchmarking/src/llmperf/sambanova_client.py | 28 +++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/benchmarking/src/llmperf/sambanova_client.py b/benchmarking/src/llmperf/sambanova_client.py index dcaf09dd1..aa5bce88f 100644 --- a/benchmarking/src/llmperf/sambanova_client.py +++ b/benchmarking/src/llmperf/sambanova_client.py @@ -343,7 +343,10 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] generated_text = '' events_received = [] events_timings = [] - response_dict_datakrypto: Dict[str, Any] = {} + # Accumulators for datakrypto metrics (None until first chunk with fhenom_usage) + acc_encryption_time_ms: float | None = None + acc_decryption_time_ms: float | None = None + acc_server_network_latency_ms: float | None = None # Start measuring time metrics[common_metrics.REQ_START_TIME] = datetime.now().strftime('%H:%M:%S.%f') @@ -351,9 +354,10 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] # print(f'url :{url}') # print(f'headers :{headers}') - # print(f'json_data :{json.dumps(json_data)}') + print(f'json_data :{json.dumps(json_data)}') with requests.post(url, headers=headers, json=json_data, stream=self.request_config.is_stream_mode) as response: + # print(f'response: {response.content}') if response.status_code != 200: response.raise_for_status() client = sseclient.SSEClient(response) # type: ignore[arg-type] @@ -364,6 +368,20 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] # check streaming events before last stream returns DONE if event.data != '[DONE]': data = json.loads(event.data) + + # Accumulate datakrypto metrics from every chunk that carries fhenom_usage + fhenom_usage = data.get('fhenom_usage') + if fhenom_usage: + enc = fhenom_usage.get('total_encryption_time_ms') + dec = fhenom_usage.get('total_decryption_time_ms') + net = fhenom_usage.get('server_network_latency_ms') + if enc is not None: + acc_encryption_time_ms = (acc_encryption_time_ms or 0) + enc + if dec is not None: + acc_decryption_time_ms = (acc_decryption_time_ms or 0) + dec + if net is not None: + acc_server_network_latency_ms = (acc_server_network_latency_ms or 0) + net + # if events don't contain "usage" key, which only shows up in stream returning # performance metrics if data.get('usage') is None: @@ -385,7 +403,6 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] # process streaming chunk when performance usage is provided else: response_dict = data['usage'] - response_dict_datakrypto = data.get('fhenom_usage', {}) except Exception as e: raise Exception(f'Error: {e} at streamed event: {event.data}') @@ -401,6 +418,11 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] num_output_tokens = self._get_token_length(generated_text) server_metrics = self._populate_server_metrics(response_dict, metrics) + response_dict_datakrypto = { + 'total_encryption_time_ms': acc_encryption_time_ms, + 'total_decryption_time_ms': acc_decryption_time_ms, + 'server_network_latency_ms': acc_server_network_latency_ms, + } server_metrics = self._populate_datakrypto_metrics(response_dict_datakrypto, server_metrics) metrics = self._populate_client_metrics( prompt_len, From 1ba3bddc4b7fde8d97c2f0b3dc504bd5cdf7005c Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Mon, 23 Feb 2026 10:43:28 -0500 Subject: [PATCH 07/17] update configs --- benchmarking/benchmarking_bundles/config.yaml | 4 +-- .../model_configs_example.csv | 32 ++++++++++++++++-- .../model_configs_example_datakrypto.csv | 20 ----------- ...nfigs_example_datakrypto_non_encrypted.csv | 33 +++++++++++++++++++ 4 files changed, 65 insertions(+), 24 deletions(-) delete mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv diff --git a/benchmarking/benchmarking_bundles/config.yaml b/benchmarking/benchmarking_bundles/config.yaml index b64855f0e..6fa71b30c 100644 --- a/benchmarking/benchmarking_bundles/config.yaml +++ b/benchmarking/benchmarking_bundles/config.yaml @@ -1,7 +1,7 @@ model_configs_path: '../benchmarking/benchmarking_bundles/model_configs_example.csv' llm_api: 'sncloud' -output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test' -consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test/consolidated_results' +output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_non_encrypted' +consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_non_encrypted/consolidated_results' timeout: 3600 time_delay: 0 # Row-level concurrency diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index c180de38a..dda5bc115 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -1,5 +1,33 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,100,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,100,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,2000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, Llama-xLAM-2-8b-fc-r,4000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,16000,100,1,1,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r,4000,100,2,2,,, +Llama-xLAM-2-8b-fc-r,4000,100,4,4,,, +Llama-xLAM-2-8b-fc-r,4000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,4000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,4000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,4000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,4000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,4000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,4000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r,4000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r,4000,1024,32,32,,, +Llama-xLAM-2-8b-fc-r,8000,200,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,200,2,2,,, +Llama-xLAM-2-8b-fc-r,8000,200,4,4,,, +Llama-xLAM-2-8b-fc-r,8000,200,8,8,,, +Llama-xLAM-2-8b-fc-r,8000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,8000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,8000,1024,8,8,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv deleted file mode 100644 index 41e9d396f..000000000 --- a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto.csv +++ /dev/null @@ -1,20 +0,0 @@ -model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-xLAM-2-8b-fc-r,3900,100,1,1,,, -Llama-xLAM-2-8b-fc-r,3900,100,3,3,,, -Llama-xLAM-2-8b-fc-r,3900,100,5,5,,, -Llama-xLAM-2-8b-fc-r,3900,100,8,8,,, -Llama-xLAM-2-8b-fc-r,3900,100,16,16,,, -Llama-xLAM-2-8b-fc-r,3900,100,32,32,,, -Llama-xLAM-2-8b-fc-r,3900,100,64,64,,, -Llama-xLAM-2-8b-fc-r,3900,100,128,128,,, -Llama-xLAM-2-8b-fc-r,8000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,100,3,3,,, -Llama-xLAM-2-8b-fc-r,8000,100,5,5,,, -Llama-xLAM-2-8b-fc-r,8000,100,8,8,,, -Llama-xLAM-2-8b-fc-r,8000,100,16,16,,, -Llama-xLAM-2-8b-fc-r,8000,100,32,32,,, -Llama-xLAM-2-8b-fc-r,8000,100,64,64,,, -Llama-xLAM-2-8b-fc-r,16000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,16000,100,3,3,,, -Llama-xLAM-2-8b-fc-r,16000,100,5,5,,, -Llama-xLAM-2-8b-fc-r,16000,100,8,8,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv new file mode 100644 index 000000000..dda5bc115 --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv @@ -0,0 +1,33 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,100,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,100,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,2000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, +Llama-xLAM-2-8b-fc-r,4000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,4000,100,2,2,,, +Llama-xLAM-2-8b-fc-r,4000,100,4,4,,, +Llama-xLAM-2-8b-fc-r,4000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,4000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,4000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,4000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,4000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,4000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,4000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r,4000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r,4000,1024,32,32,,, +Llama-xLAM-2-8b-fc-r,8000,200,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,200,2,2,,, +Llama-xLAM-2-8b-fc-r,8000,200,4,4,,, +Llama-xLAM-2-8b-fc-r,8000,200,8,8,,, +Llama-xLAM-2-8b-fc-r,8000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,8000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,8000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,8000,1024,8,8,,, \ No newline at end of file From 47e6dede4ada8241873732e3c87262cd4ed8987b Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Mon, 23 Feb 2026 10:53:08 -0500 Subject: [PATCH 08/17] minor change --- benchmarking/src/llmperf/sambanova_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarking/src/llmperf/sambanova_client.py b/benchmarking/src/llmperf/sambanova_client.py index aa5bce88f..d8aebebe0 100644 --- a/benchmarking/src/llmperf/sambanova_client.py +++ b/benchmarking/src/llmperf/sambanova_client.py @@ -354,7 +354,7 @@ def compute_metrics(self, metrics: Dict[str, Any]) -> Tuple[Dict[str, Any], str] # print(f'url :{url}') # print(f'headers :{headers}') - print(f'json_data :{json.dumps(json_data)}') + # print(f'json_data :{json.dumps(json_data)}') with requests.post(url, headers=headers, json=json_data, stream=self.request_config.is_stream_mode) as response: # print(f'response: {response.content}') From 7a6b0a9372ab19d313f6b2667bc4fb8fd5e7aef9 Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Mon, 23 Feb 2026 11:00:44 -0500 Subject: [PATCH 09/17] add encrypted config --- benchmarking/benchmarking_bundles/config.yaml | 4 ++-- .../model_configs_example.csv | 22 +------------------ ...l_configs_example_datakrypto_encrypted.csv | 13 +++++++++++ 3 files changed, 16 insertions(+), 23 deletions(-) create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv diff --git a/benchmarking/benchmarking_bundles/config.yaml b/benchmarking/benchmarking_bundles/config.yaml index 6fa71b30c..4dd33bac3 100644 --- a/benchmarking/benchmarking_bundles/config.yaml +++ b/benchmarking/benchmarking_bundles/config.yaml @@ -1,7 +1,7 @@ model_configs_path: '../benchmarking/benchmarking_bundles/model_configs_example.csv' llm_api: 'sncloud' -output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_non_encrypted' -consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_non_encrypted/consolidated_results' +output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted' +consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted/consolidated_results' timeout: 3600 time_delay: 0 # Row-level concurrency diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index dda5bc115..6d510fbe5 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -10,24 +10,4 @@ Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, -Llama-xLAM-2-8b-fc-r,4000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,4000,100,2,2,,, -Llama-xLAM-2-8b-fc-r,4000,100,4,4,,, -Llama-xLAM-2-8b-fc-r,4000,100,8,8,,, -Llama-xLAM-2-8b-fc-r,4000,100,16,16,,, -Llama-xLAM-2-8b-fc-r,4000,100,32,32,,, -Llama-xLAM-2-8b-fc-r,4000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,4000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,4000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,4000,1024,8,8,,, -Llama-xLAM-2-8b-fc-r,4000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,4000,1024,32,32,,, -Llama-xLAM-2-8b-fc-r,8000,200,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,200,2,2,,, -Llama-xLAM-2-8b-fc-r,8000,200,4,4,,, -Llama-xLAM-2-8b-fc-r,8000,200,8,8,,, -Llama-xLAM-2-8b-fc-r,8000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,8000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,8000,1024,8,8,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv new file mode 100644 index 000000000..6d510fbe5 --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv @@ -0,0 +1,13 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,100,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,100,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,100,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,100,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,100,32,32,,, +Llama-xLAM-2-8b-fc-r,2000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, \ No newline at end of file From d4761e6f51ad765ae65a09e8a58bf9e5a00734db Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Mon, 23 Feb 2026 11:04:52 -0500 Subject: [PATCH 10/17] fix typo --- .../model_configs_example.csv | 24 +++++++++---------- ...l_configs_example_datakrypto_encrypted.csv | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index 6d510fbe5..0d30a59cd 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -1,13 +1,13 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,2000,100,2,2,,, -Llama-xLAM-2-8b-fc-r,2000,100,4,4,,, -Llama-xLAM-2-8b-fc-r,2000,100,8,8,,, -Llama-xLAM-2-8b-fc-r,2000,100,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,100,32,32,,, -Llama-xLAM-2-8b-fc-r,2000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, -Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,2,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,4,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,8,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,16,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,32,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,32,32,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv index 6d510fbe5..0d30a59cd 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted.csv @@ -1,13 +1,13 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-xLAM-2-8b-fc-r,2000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,2000,100,2,2,,, -Llama-xLAM-2-8b-fc-r,2000,100,4,4,,, -Llama-xLAM-2-8b-fc-r,2000,100,8,8,,, -Llama-xLAM-2-8b-fc-r,2000,100,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,100,32,32,,, -Llama-xLAM-2-8b-fc-r,2000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, -Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,1,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,2,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,4,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,8,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,16,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,32,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,1,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,2,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,4,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,8,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,16,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,32,32,,, \ No newline at end of file From 9adccab382df381231201f8ad62d334ec2c648fa Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Mon, 23 Feb 2026 18:20:56 -0500 Subject: [PATCH 11/17] added datakrypto metrics to consolidated report --- .../synthetic_performance_eval_script.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/benchmarking/benchmarking_bundles/synthetic_performance_eval_script.py b/benchmarking/benchmarking_bundles/synthetic_performance_eval_script.py index b267319f2..adf4e0bd6 100644 --- a/benchmarking/benchmarking_bundles/synthetic_performance_eval_script.py +++ b/benchmarking/benchmarking_bundles/synthetic_performance_eval_script.py @@ -304,6 +304,18 @@ def get_batching_frequencies(uuid: str) -> Dict[int, int]: 'switching_time', 'request_batching_frequencies', 'representative_batch_size', + 'total_encryption_time_ms_min', + 'total_encryption_time_ms_mean', + 'total_encryption_time_ms_quantiles_p50', + 'total_encryption_time_ms_max', + 'total_decryption_time_ms_min', + 'total_decryption_time_ms_mean', + 'total_decryption_time_ms_quantiles_p50', + 'total_decryption_time_ms_max', + 'server_network_latency_ms_min', + 'server_network_latency_ms_mean', + 'server_network_latency_ms_quantiles_p50', + 'server_network_latency_ms_max' ] # Remove missing columns safely From 302ab970a2f9e353df248207b9cb1e290d9b4acb Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Wed, 25 Feb 2026 09:56:58 -0500 Subject: [PATCH 12/17] update configs --- benchmarking/benchmarking_bundles/config.yaml | 4 ++-- .../model_configs_example.csv | 24 +++++++++---------- ..._example_datakrypto_encrypted_multiple.csv | 13 ++++++++++ ...nfigs_example_datakrypto_non_encrypted.csv | 22 +---------------- ...mple_datakrypto_non_encrypted_multiple.csv | 13 ++++++++++ 5 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted_multiple.csv create mode 100644 benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted_multiple.csv diff --git a/benchmarking/benchmarking_bundles/config.yaml b/benchmarking/benchmarking_bundles/config.yaml index 4dd33bac3..13a2b5e7f 100644 --- a/benchmarking/benchmarking_bundles/config.yaml +++ b/benchmarking/benchmarking_bundles/config.yaml @@ -1,7 +1,7 @@ model_configs_path: '../benchmarking/benchmarking_bundles/model_configs_example.csv' llm_api: 'sncloud' -output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted' -consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted/consolidated_results' +output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted_multiple' +consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted_multiple/consolidated_results' timeout: 3600 time_delay: 0 # Row-level concurrency diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index 0d30a59cd..a7391adf0 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -1,13 +1,13 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,1,1,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,2,2,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,4,4,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,8,8,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,16,16,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,32,32,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,8,8,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,32,32,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,20,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,40,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,320,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,20,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,40,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,320,32,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted_multiple.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted_multiple.csv new file mode 100644 index 000000000..a7391adf0 --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_encrypted_multiple.csv @@ -0,0 +1,13 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,20,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,40,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,100,320,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,20,2,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,40,4,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,320,32,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv index dda5bc115..6d510fbe5 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted.csv @@ -10,24 +10,4 @@ Llama-xLAM-2-8b-fc-r,2000,1024,2,2,,, Llama-xLAM-2-8b-fc-r,2000,1024,4,4,,, Llama-xLAM-2-8b-fc-r,2000,1024,8,8,,, Llama-xLAM-2-8b-fc-r,2000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, -Llama-xLAM-2-8b-fc-r,4000,100,1,1,,, -Llama-xLAM-2-8b-fc-r,4000,100,2,2,,, -Llama-xLAM-2-8b-fc-r,4000,100,4,4,,, -Llama-xLAM-2-8b-fc-r,4000,100,8,8,,, -Llama-xLAM-2-8b-fc-r,4000,100,16,16,,, -Llama-xLAM-2-8b-fc-r,4000,100,32,32,,, -Llama-xLAM-2-8b-fc-r,4000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,4000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,4000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,4000,1024,8,8,,, -Llama-xLAM-2-8b-fc-r,4000,1024,16,16,,, -Llama-xLAM-2-8b-fc-r,4000,1024,32,32,,, -Llama-xLAM-2-8b-fc-r,8000,200,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,200,2,2,,, -Llama-xLAM-2-8b-fc-r,8000,200,4,4,,, -Llama-xLAM-2-8b-fc-r,8000,200,8,8,,, -Llama-xLAM-2-8b-fc-r,8000,1024,1,1,,, -Llama-xLAM-2-8b-fc-r,8000,1024,2,2,,, -Llama-xLAM-2-8b-fc-r,8000,1024,4,4,,, -Llama-xLAM-2-8b-fc-r,8000,1024,8,8,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r,2000,1024,32,32,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted_multiple.csv b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted_multiple.csv new file mode 100644 index 000000000..2ed06ebce --- /dev/null +++ b/benchmarking/benchmarking_bundles/model_configs_example_datakrypto_non_encrypted_multiple.csv @@ -0,0 +1,13 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,2000,100,10,1,,, +Llama-xLAM-2-8b-fc-r,2000,100,20,2,,, +Llama-xLAM-2-8b-fc-r,2000,100,40,4,,, +Llama-xLAM-2-8b-fc-r,2000,100,80,8,,, +Llama-xLAM-2-8b-fc-r,2000,100,160,16,,, +Llama-xLAM-2-8b-fc-r,2000,100,320,32,,, +Llama-xLAM-2-8b-fc-r,2000,1024,10,1,,, +Llama-xLAM-2-8b-fc-r,2000,1024,20,2,,, +Llama-xLAM-2-8b-fc-r,2000,1024,40,4,,, +Llama-xLAM-2-8b-fc-r,2000,1024,80,8,,, +Llama-xLAM-2-8b-fc-r,2000,1024,160,16,,, +Llama-xLAM-2-8b-fc-r,2000,1024,320,32,,, \ No newline at end of file From f41abc7d8d1c367b98c1965db87f708dfc8522a1 Mon Sep 17 00:00:00 2001 From: jhpiedrahitao Date: Fri, 27 Feb 2026 19:43:41 -0500 Subject: [PATCH 13/17] update bundle reports --- .../datakrypto_tee_performance_report.pdf | Bin 0 -> 693962 bytes .../datakrypto_tee_report.py | 979 + .../datakrypto-tee-performance-analysis.ipynb | 27218 ++++++++++++++++ 3 files changed, 28197 insertions(+) create mode 100644 benchmarking/benchmarking_bundles/datakrypto_tee_performance_report.pdf create mode 100644 benchmarking/benchmarking_bundles/datakrypto_tee_report.py create mode 100644 benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis.ipynb diff --git a/benchmarking/benchmarking_bundles/datakrypto_tee_performance_report.pdf b/benchmarking/benchmarking_bundles/datakrypto_tee_performance_report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ee6a6d5374c0df4c0abe052b7c2fb9e15f24c6ea GIT binary patch literal 693962 zcmdSB*|xIWwk3GKpW?Sbv7`_|Dp9bY5Cjyk!U{nY1VN1!ab6+wF7NYMlkY!!$BB$+ zE!w%si(D6Li7qCy7<0@qdhbI(pUgT)7yAeBfBm2T$N&A8>A%zbySQBcn)`{LU%vkB zui`)cx~1OlL;XnN3_UHaTH~y;~{_^o>Y4IdT^yB~He;?lEFKC*0>Ftr+ z|AL%HGEP2^|9C^Yy!_&s$Y0Rvcm4jicX6>Ueizq&{uG}SZT%0A`qQ)j&7(Se8sGji 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 z NJv_h*>(Vo+{1C1RRhHbg4$6ex1aq)np15{pKH~M-sC8*p!e-f%1GU-;8UmO~N z^jPsD0U11Bg?1HYN{sUURAe?`MRy%s%)oL`^n#P9>(L# zjtP=|<--oe0&FmMua77vLuc#dWB`++ewkm@2lU`ZQ1gOn84#J6A9X)+#Y5G7n(ZF@ zpUN;BgaiKjIZXlr;&VIDqUC7il_>1Td~(s#PSVnnZ5xv)fc26ugYc=g`M33AoyHF= z?38-A{Vrw*2f7^Z-4vT#azU>~zi^0il6uX4r#P9H-myiKc5eLk!(+`uO2(;1uZNsc)IMY`3-yTyinxYVJYxLQ}swy$AQfa)lI0@M!sc;BJVb*(xm+z1>)rifli7Ne+Rt209EyztTXk>*AQ zwVjYaqO6xr<#VU@p!&vaI-|3y4FSq+Onog1$FX{spQ2~)+SX0A*jDzKS>=RQ_{K5{ zt{;f#c`x-2i|CCpc`|=!k_IS)#0ll_HFk1Zk%wvO9Qr$rKEluvY`2g0S;>r$ z!6yeZWt7{tsgd*OV2Z%6f8B#8OS4CIQoLDD&^KLvja!-bMx`N4I`i%=cDWSAi9yr$vfG9pTTNx`bjplHu=|TIaU4Obe@r) z?}o`$%7gZ;s1U@&8pe)M+4tp1vB-J<_K3xh$W8kWn3Ookemy1q$OQ(s6yLb(+ zXwTiEK5h`uOM5Gia&$z2fs|4`#@hD1d)naQ><~ZR8`NpsG(QN8HEamPxqGD7JoSZt zE)GzMcZTwL(r7|3Nr1M1D0y_FlE_T2!6y;Nx9d~A1Hv7Q9X~)$MwU7gS6^q@b2_d0 z2O?hD%Di`>*^kyiX71n5EKPrLqRZHs=Gv=P+Iz-NO(17Zehob>^?*>aWVdcTU}zXQ z8<+u?xXfz2`3W`^Sc{VNSl;H#2^u}o>AFH_Q(dgdm6h-U3Y_tAZNO?VPCY0 zV$XhuS7uozpPiE~&8F zY+NV|S%`bQ47n!popN(zn;@qv@&uf5yD6pi<^E~r1Z);fM}gJk2K{VTXlxDREb8S$ zrM3j4XywM3HV{h1K0?TuRzkecBJ};XP5AgRa2Ok8Ij7X@buv8Xs!=8L_$&q(;JVU5 zB-luy7fd=+5*B#pf$xrYfBr$}M#A>Ncz(TYfcHIxTKu2YdCh3kQMK7=g&3vBjagO9@_ME8Vo?9(1z*j^g7 z!`*8fyRV}p%8w7*@GlX)Y3w7b*7_P92!hRCx;WQ+6`~+)|A^Lh8etWFFpU#t8Jd_Q zF1qI?*9;4+V}{eo?SV_B_wfH-#kh4Aq_R4X>NDv))!+G5VSnfYNh9Z;;DH{viUG;Q z_A>)fHRQR!5w_D~6aND+3G(;KJ=bx$7*4SJF{j?ILm8S<5SN29bc`;5Vfvq|$$IJO zcrq_$_t&vNUrXlT6%>R*VGucg-&Jj}d?z5M&y5FW|N7=HMu>X-t7Z=o7}pJi+0pyg zk}7%+uoln9;8d9dvy_4e5OdFu{%6-)bZ_h!W^L6w=20VwT!-pNq(7LCYj{TqOL}MtaWUw+PVAF))<8~N}Csdp&g6Y>+1X~ zJoZ4zTTONZA1wdeka;~_cV8DqFtZCyL=L`UeIR}cUtIoe0gEK0!L(+*v2mzs^f;Nz z+63aeiw0UcOv{_YjW*{OxlJ`LcnyXLFeEaE`{?jxZ*AfLj)_>1z&rK()Qpur_Vm6a zw<-qr#`YN{0}!wCxY7D&Gn!r3uVOHW$+c2h1`N1@2Ceb0gFWp0sZ$$DW}jBJnvpz-CTA1Ai#kA3HMym(6p5M3M z<73ugibBn;BD-^5{Ci~m>-jbM!>0)482QaT8&RAo*SGt%{)PANR<>T*ayuoZ?|Vp` zVnR5tJ6O9UNe)_FovT&JF3lyiA#je{`9{NB;R_Deu4tZT*NlDnIiDP4vP8>_b<0@) z{VQ8m_7vN`_S$CguDd+BonIF9VQ8;|DtmcI$32Ii4KFiFGIe87OwD>fQJVveyExrI zUza-zI)BsE;e9y$UHh9$n9F9$%F(&q9{IMc9oj6imR7s{KRfzTl0VJa~n5cFg5{n%*m+zvCHJyEwZ)p_WgGD|M{UXlFUx+CVuuL?Q zT7H5fuNn8;U|UdGst^e<2J&w$AFQ5pW>%Zo`Aj33sovw?t|Wh65^H!mF-SVUQq>y- zQ{sayQ%sHwPVRB(FDUb?(+0R+V zx{SMY5q-O{=pxr#-MB}27EA_{v;Bd6W8eI{Y>}fXZ3$^S_|%~~9^oMIHOmr6m+@e3b2csv!Vk5 zCYP!3{rGAhkN@*Fl0DnynLp}YXjt9u`B@~a)%+v$XA=|;Lt8n~QDMQXo6I zs)B$J7ts9bUP5eus0eH9{e?MdsdVFmJug=W>yfQgD zJ(!=x+E9ij@sU_L;)S(45cvFNo5&eBsAl}k;)^kLftrbFI@!$C5l^-HXR|lC%xv^( zhkv$zw}BvQLQEb6-N}}T%75LYgJ(xq`TXu7oZE}T6w(Fqb%EB;CR#bf#pZ==qKPg_ex7?}j(;mx*es7v*gG@KhRV$gragm*uNqo#Xg~$ zfK3Yr4Vh4A4%=L z5Y2eBHJ?YPkS8Z=wV^nFitjvdKv(~(ga`R;^|xT`7H+e>@P|7X`Ax-1DVOtj z^Hu!rO889Jlq+k#gU5R8%oNpF-y5}U4dmj3N^GRrMQ0D&t20q1Ii@>%4sWC0+^3Bl z@4I?jOG<;K)U6aD*{uend`ln}N++F+%Y?M*Gds8HUi0zj(5)d}t@lq^|IbBpz1fy} zd%s-Do@o}M6bB2S8R&)k7AbUY-JQ+UOWn0@`Oo1;{`C0_e1e|OJptM3Vu45C?k$h) zf$BHkD4D_O@2Xp}g-K4&XDAvTU6_(o0Q}4Dya0QfS4+=Gh{pS)p!)B1o5D)CRZ$AZ ziRJu1ZWLO=oq22sU?`-{8t<0jh2?4{t_;E6e(P0Ic;D(3Gn9GmguT68FFQNz#}gqv zo}Ub>!B^2Wa-=fL$Lc7@iO2G?;W{zl1CWiToFl^ZLv z+5N9w7f{&y%6T+JnA#Q9#cK(5YcPCN=BQ#5e}Db1ePhtAPanR$)hn6e87-La*~4s9 zKjQa{cjwRpD7s${oo8xPHn~2VTv<`DSKFNF-Qj-VbM1;x*~s%)501kRp`P+d@n+xR zL%G=G8`d~!e@P0~jC>R+knLgW4-S@I^J&%g42zKsNtOrxCY3urk9Oq~WF1fkCFT`f}HeoECmbIOD z?T~qO>y7)L1DHa(6T8HAx>&hN2QBd4NZR8`7a&gM|1Y`An*ohgmY=JO?5^?;Jp~2DHe}XOP+1n}k|Nz>Vh_^sB~nhj}LqoOFYgxi;)us!gAIpbr6|{vKJz zb^Q6DgHhdS|7-E%!}r^myys?>D)+|U5hZj>ll_OB*X*GO zTFhGG@GSl5gPb#Sg;>JKe)2x@IEzf2u~xS{eMoh4-CZ9byxeBlzxJ;&QZC<5wbnSU zY0CQjZx!ypwP;r4$*fvKr`Dg`OxiA+DW##zcnR(|qs*P=2P2@$4%sM|wGUOxK^vdH z!=SNUYI}8!F}sbSI~`qC0H|Ogx-zX7kf6(DVU`Z}knc5c?=aI0rVv8ieY1qyYtO7T zRQ~^utpKD3_r2p!fv5@_Imd9vk^RdgC;aNoHIO{~T^74!J3t<_S<)-^^3m$qe^70w zSsR~5HNpP0z1uoh?tj}#|C{$O$gTWkj;r#1mrkqP)?KJ8(9A+|%{az-;plUEN(z-# z^BwCp+5Fdwh+y{Z{_!$kUeHF@9SnJAm-&YXacbgg3Rw;{6~XKCj@j+*M3`xQ_Ls6; zlm>n;jFfZzei>w+4G;nz{y)b4wf$7R>mSD-OO$Oyc9l&wr6g2BNQz3L5T5^UeCFm{ z>%6Y-b^QOg){QlfIaBY=7~{25JI*S*EFR{Z0jT|L%7Uv<#*kLYXpto4dqTeP6+c~) z-Fp$*6!5i=uX-hL50(F2#B3M*7~gS&WZUdGGr` z^R?3sEI8+5YO_0SFG*7wx(KD_#%?*1iGD2)nbXo^KO6lT3|5*|myX|V@M1RLwl!jw zEBb#9u|%@ge|5V|Tgvx~AMIJFw@9KYw|?090V%n?WocbuY=m@DI|l~pLfNuc79i(i zEX{44m#A-|yPHO}@vk4FZAeD^J;hd7Sy>g`4{le!f1U$`kPD|5eES^fn*KWEO=|Py>^{i->Xeki39Ka@WgK$f z#r+VD?#)9QW_;ye?`0jt>Q;<%np`xCEHX5z39hlmiFMn*j<` z2Z_QiGt|96QW266FV*hGzkYIqN+aEN4!=6rhYCpfzEdjTLZ|JKyY z5=}{(XIPZ!op{Io9GB|joB8I8PjS{f%umd!b_H5bO_0rxK!a$FWqB369-{MlCe*dl zsWw|GVqlhU%Co+EcJq!9yPOS9J97wz^@_!Py&WHKTzox8RfBda9}Jul`*aBU;L!~h z5*Q&fwva zxdU=bAGK^`1xIgMSkRF z6%i>^YWdFuWVZR(zL#|NnC#-lIPTb#b88%`1XNrs~r9@F8kLhEwy2C|Mq{i&5X0!euoNtC}(j&QqN95wd+l4 zHNZo8p?lgZHEx$TO~QqWTAq;TdGXIQFJz8YJ%I9e1W}WPm4+JY@tWZj4wg$}Ql4%W z&&8ovZ-_)pxN<$Y*7JklwpzV%(z3nU6sGA9TW%HnR|i}S^6K5L-=p>Q@76PVyJ7k0+KBYcI6#Xgva{0=eB%5sot>)K+b#<6% zHO#K2$2-QheQ-C&o}w0}BsE1gw*J|w-MCI3HXQAa=n|w5`ETr5KkJ=fGD!Iyx_iaS zx0~1a#wANfAH{Qf;@RVE1nFesUc&AF8O1tAJ_DXNw&&Zi*Nv-psmO}XXf=?&4j3q`y!|R zedd$a*-edpRi8XFT`b=r8ajBewNlCngi)%P6AIx|2srS827q?ScQ*Ggww1^4ZG0i& zWQ>|?F%3MY_1sL=o}CUxet)dF*un7in(Te#LWD>3F>QS^D^`%_>r;NERHpx&lLnr@ ze10iLKrUKcTZ86vyl+<##S1b<-F3RFGGMOT#o}eGJ1gtnwB6o`ou+zPtr3jD`;5$} zVb861yV14xZCSBpw?r3~*&b|$BDeNKz$8(@ck?$wGq>$-R>}+YqO957_!^O$Em?bI zhjKig-g0*?y$cv;q;~#|?Lg1!>>ob8k&->!ZzqoN`s>o5KwE|3_GG(_DT!LWz8!X= zJiEPr7eMMc{)}-;MV7f2O4Sy&Y^iK4_Rj6M%#LK>EKyJN z9(4iidnL?{UkUvdJIPA*!6uwEncDG2UwSDdqfnP$NA7P3d$hO?=X+`79!gz0wHV0x z<}mv1OIMZKr`jL<=}%%CUUOY}M)?#6JfG(7wyeD=qKN zheoMR90mkUNNV9Bzb;6x&tIds8&-RaYHAIN>L0fHAN24KLj%d*%1wG!?)j?0ZNb+F zH!gtHy{L7W>F^D~?4VSkzE)t}`Fpgv%h6<*yT?oh-;LbCD;JG4e9RX%VOsqC0f;Vi z{g5ua+~qDv5#%rsT6M%(z~^^Jc9kd9-fTQRz9wV&#CqIUU;df7{bn|#==JzuaO)*W zB%5?*iqy>1>a$E3&EXTF9~oW?Y#=WBn{n#L1$faI z`(Ja0-)Pkj9x4l4E?Tc1lDwZ6)5S+$*^DvU2sGw85{Mr%1sLRPv_=?oD=viRPR)Oc ziOl$DZiR1*XIXZoGBBp+%`RmFk63B^&U=e@ZQ6d*e&X{1o1PQIo3X@GpK3SkEDff-4s|yJHKig zsE2Cz<7l-X7gLMJdqfvkPpnr?sC%~_*89s!jE_KKi6QI$VexCH{DwkBVpz1i$mc}d zp!Up<7snt1(TJs|-{Nv{+7y4@LHE}?Xz8s|mNc|_j#bIoshcSzY&0F!o`2@|<@{nP z2o0_;%8&2Lke&|q1zXCfAFs|~bDJ%Ny5GOo!J+-yFLs*7P|%B=>>k1a8{MpB;UFuK zwYV_Xeg=sBhQ%u_7&~N()kpo5!d8{l>xVP(00t8%2>|EW%}d8ttC`l4uQKip$6I)7 z5PL@z(|v)X!QdL$MZkc704i5!iHWxD&iD;>T@8S#h?w(8U_sUu3q>>#i}qcq;_)BmBxeihGrf zkj!3hPBtu+g%Q}S{kkC#@_d5vp+LkXua(Vh6&^E^o}yjIJ0uviK4n<}f34g3SB?IQ zE%)!!%x3Jdxz0#qvOKHG*9Z9G00uFccO(e2K8sN{eXM56*KeubfM)8rP5b#hXrH-7 zGag-AkLR--nMiUE8p`X@9ynRubyCZ2TKk`i!DlaDh#|NlFDK31c0i^onGDZ(x|F1f z)F+R8`V5xpS46o{`o-pxL}Cz3Q}a#Q-QSvW{l$!T6X^n$A4%m?2!hYC686-vawrq- zDIba7FWfS@TQO>HgkM*}U#iNkE-kg9J=gNzFuAoqVskv7m^-6_7dkYA!p1@D+Eil> z7Nd8ga{GHIgw=9aNFOJo_dVM?wPq75=|Y?-uDIkn9rwI{kNq*2jUA)~eLLojR~Ccu(7Jq`^J?M!8kvmPG7T#2EhAKfTb_vz&uDI3-colgvGzsDKl0VY7l!o@l^fHa`#ZV$1*$g~ zACy$N;`9Db=e7GE+qtofh|r!*AF_RbIjcKb)+%Tw?lZllsO2B z+)0l^b)EXp1L>>8Ew8oqv#1>euN5wjP94v!_96bb42?_S19^te z`84UVxl8ZwNdvc4RAo&R9DJmKqNR$1+#R*$y)2Bjy{c|<_GP2&{tPL9 zlbn{N87t3=x7xrvYoiSkAK3d7&yyZ;b2X#J?E^zF*Dj<39PsqMeL z#n#~Td^JwRyVIJwxgsLY1mspIKtg6PqsDmAi$U%+@DqEnQvdW|zXsiPq*+$#s;LBn zl5aeUlx~{iHZ#bDbN<@nMaSkZtIr~sRi^)|@LC7Y(j@1pezi;rd6Qe-mbLa~KUn3S z=HiW}8Rpp6pLYFGt62SYb#Ku36e$#%In<#SpWpO`BHieo&(Bxd05^ye&Sfr#Niv)e z%gOrgZ%qXqZ#8?;C_*)vBjd{JIS&ag6NXi(G9d%Viv7*J@cMTIZ#@P}ux_d5z2)Q-yTW;4ChyMA*o%Y_9oxuGTiqKU})oD+VN0$V6a) z7lJ!PYP8-Sy?jabp0^}l$wmFiVC$ZZeJU%_e_6%b1rB!$*Pk`f+!Biz(^pTn0Yipw z^sD2G{5Z!sTPNS#zg!T>=qjClz0Tvz((iUAbS0Aczss?7);HNr%XqZSPUT@`fbLs4 zf$7VF`25T^|Ki<07oVQE&$#GKK>%gXc+PwA)>!$DAC$3q?2plKGy^K(m{fwHRP0qI z6MX@5pj0rqPX>Q_>|csGwu+s~!t5-MO%rTTi}lDQyuXNZr^>h*Rbai>q0lrriNOg2V zeVXx<$Q5kJFvWnW^h165<*UYg=zL>qKfY4jxQujlEk46!(K!+nH#2hmeR`$@u5iIm z_-IgYD&XrC>h3#cKHUxTKh8<16D$O0-GFKlJ4{62U1Jp)a5-opXVrwT)(O7bJ(>^4 z1{#dK`^^2JFcF1+@6bl+s+<~Lo13VY-VS1h>m6PZuPXdk~SwljV3#>u3kDYaNs&jag!*-{WYhXI@6ku@N4>T zOv&YcHbl&%av(Fi1oq-ytTxy5XwWDT%5_ry43gbHORxC&d^j9@RH;O8qn!^~s8K&q zODs26qMA{|7-EB(3`VTFxG{T5`mt+Q_V)5U+vb1a20vrDD5avkLuHZAIij30pDR{r zH@5p`_SO%YwlLp(RP6vD9_bjz`vu_YKcoggroePGb|NY8ZF-n_VGr3mq^-^Dvl`*V zdq>=J5RXhilN^>xtRW+ADHS)wiRb^$n%_Hr(nok*JG-0 zLdJOC{cJ!?x1N6lW|q5*>;uhFMrzQ06h32tzEM8*?*}U9;D8ByWN|E-R?P=L)T`4c z8j|kW%bA@%#kJE4lHb!!^^gLY7ML}-(}x(!hs~TMO}ashGbGc&WFVaN0O>1%d(~_f_MnlD&p+*X0=4 z)JCx+<-Qo2U8-iy0?=2P%uhk(_h9NAB;XQMCbRXrmH$%Fr8a5PkVnA) zh@S@YDk1v%v#Zl|)5-BV*$hI@EAVnvc`i1!XYZe*ey9$?Wr05(?!Ykky77d|Q1P>A zaf5nxgc8)XNMHKfhjMw->6x=E1YSDY^pagT&=xSVoiMh{TzvkH+qK(t+M9_pl$*8h zWMR6SR{eQc;I~fZT_k}0NzB8X@PeTEYd&=FSvCMBM5>TZF3p@i&gZ6Bi7Kz(Ov)~r zcIB|n6ZlRTcD!DFx>!f*oIct0TywMNhClBBxJTE;A}X~~`r#25rq-wMDev%t-M&=k zMs<|joWo$6yY530q29aF%g33rS7Y33?uS~{^fPGjo%u-y#=q7fpM1v6u853?;Bvx* zqA(`CXV_;U%Az{oiMpu?nX?FeH?(uko@!|QMdK4)(jRp`rE>})b`s8_P>86Jh;qj2 z;n`ko!<+4CBv(Fk&N{YICUx^#OyXzTjo!P6El$?8F?*R_Jmy@;`&lV`L z*!P;}RPKdQ>V0V((6*@dQ~PD>Q3n4^0_@`2UTa5t%Fa@??SQUB*!6;7f$Xz*PG{5R z=36LC5nii_lR#A~jiS?>pKcO2-@SkgTJ8@NYL#X8)rFn)Ivpf?dfO}ixiE;-s|{j* zBU_O?X?Pvoe2^cYlU2D2Z>>~ZE62=rJBa}HoM7!3WIWw!Z}nJh=ITj2EcV06EXmk~ z8To7)g(JeB8TcKL#$q%G#u2m=`-?*$X3FbXt}V)h##1w_4HDap@hu8>qPFe!G+CWw z*z9gn!d|W$r7f)#9^?y%33^1PmA$E&WJ3n#bA8hG6%1+8(*mMs-LwzDjhKLo@qieQm5b#;kr!*+DV)TX@|GO3zmPL_~+0BN=3 znO$!<#o-WtK_W6YuvYtq@SemDGnu8WoCft&moBB8$+H#j?tKG+-ahL7=H!E0rh?>a zi=Y0eh~q^n5r=;NmP{a@WSFE_bFw;gi>*a}(}n-h3)Vm1w=&E3(lQWY>&IVI^p~(& z4l-W53WAaN+?aE@zV$O9eaM|f&)6uh;sA;S7}NjJN zH6IeMAcTAk);aSv%)Rq3(8!*zg?Ga+e!VbVzG7Y8L{7>O6VrqhPOCG+j=ogB&=l-LfNTsn_Hnl`fF$h;{1V!P5Lx+kCV*9vcfW&;;C3CLSBeC1!~Po@Nl zdMWKJDg{g4z4b}IPac_`IyIM$ST6Zl4>rvZvb%1}L89KzNP$f->znOjc&$>02D*3e z91XubFJ873wKzlM*2E^kV`5DhMs_9zGxIQf_bwJ%%*M+1m>Ow$0JF*QwXYxU5JmK0 z%Re<&eNF`F$y4o@P7b>ojaTn`$;Le1u0_{;{tRMp$SXJ3csf&F$OQm>9Ol<=6ARNB zKn!1;T+OZ19)@S9bVu8Y-Focx9`CvvhKbLJ}rscL7Kp?NuVN%s4ys)&0ljJywsvP)#t|| z78@{XCm=1Nc8bAA)7s6=Gxpm@*vW5?XghD%wR1=wc{;f4)zxP-T@+TtU|I_5*k-?v z*b6!u<&&*C=c%2ZjAaXLL)z;pHhy_%c(tc|Ex}1J1j*|p5KIgpz~y(Ff}v)~5!t1j zbONG3YWc+gqrqgBpndthc~G|^bo(RcZAg9*(QK+_Tq5y`E|02AQY( zQ{8AlWw1e6y}+#JzI23KRH9o#USTw{4#h(DGCLh6!}pU`K{rMT$O+tO_oeN&Gm=*# zOmkNUGRYk`gw?+L=iiw6EqAN5z?^Ijpy;Ig8!?_cjeEIMUr!(rW!88#YFtA$ zv(qktx1~pj-D9sLq(((W7D7G-;e&!mO&+o*@NP0Rq0NWz&344WY(e`4!Tt;oO<*V6 z+s6t#M#E?&%g^n_&Qu;WdY%CN>V*un_JP!>mikci&OI~Q^V|Q&1MS%M3zu}%ke4Pn zl7W8fnuoB4YhmV}cCQFVK8k?WL4^|yKZ+vZdZwXUd9xa8Rg7zz-hSA54w_-!!szku z#q}CY@teqyC7%A&Yi?1EFS)%<*QlDmEj!no;WtLDG+(ejvo$XntHjt{C)*}6T}_w> zse>m@f30s~Rjl*|a}}caO6j@>G8!*aM&2%{sc|#=xCT;A8E23hQaoRzm=jNF?IqK32?}QYUh1`|bRfGQy);$1c4#bGQT@X-0DYv*ZVPI%et+$Ul3R0#! z(l8^be2M3m1ti*d>+zZG?(F0Dh(J^FER?UUL+uJtYJq0rV6ar4CW%J@Cn66G?*beR zTBi}VjP~dhF*o1r)_9M>XJh2S?Sf?C!#_E@leJ=W@+oyDuWK(~wa>PY64zp-lMfC# z$}5;hsr}^Nfq$O#keRzC=iuWopl_ky%qZnCnk!xB{bi5XSDWHOyM(zI%N!M*vfQQ= z6ochK>cGMN2^*u0Qh*3lJ=SWhmnGT-EscAh0;cceu7;(nmhUb%yV|)T_iiO~3w|gZ zb%x68OHFh1owR%aAHlc9>n1(%+dCSd^(-^0_9JD z_{)vsEKXdU_GG7a#A)aplGC()8@ZJcCsE_o@MZPACD|!zZu%7j<=wpfXwzZke%V#b z{_s8Tf_>S37DZVhjorP$qm4BSxd1}AtT7;k!IZG*&ls9a8T=l)1-!q-D#Y+r$e!j0 zFh%Yahwo2gnt)7^Os_M?$8jLBlSYNp=XDQkoEHkGPcia*En2&_VG#-hJDPd&9Ghje zp&AI{fO0V6q1TdK-&vSZcuKHu2P z(z!)~z4ksg4VFtjxaDQcZs&{n=6mFnjy?5$yEIc^NwVCf(8BEmx}uwalp2eI*M>uW z2x4&Mt3Dt{x3Ddqs z+RA&`@d{W~HWyx1rVp-UvZu!V z^5^YtSNZDm@;bIazB8YQTQ<}rn7E?$WtSWtgT9b0wjP_zb6UcCO4K-Y?qQzudkpW0 z-oe~h2jp(T$Gh|Of*_)f*lULZHTkr_8w+c9C%wA}vz8(XWcX6+__chnSdm|V!xA7| zY&p|Ws_EA+u8SXr<#oLk9KUYwZ~EsmjbbJY$Q_hhaooy&z;SE%XQLI%Ggb^d$?z(;eF*0 z5Qzy11bURTd*AoV^D^vqF~ia$p&{>~AK9?u8y)+`+rG=(G~(12!+h6nzVXeHwHsm> z4K_=`ADuSuz<&JNrdM^lo?fWw6D5~gGCvBb`?NexPlO=8_h0kop%PK$KF-hL z9Kjs&X|3D5emK-?LaJ>yb0lWQ_}gq`j~tAKwy^KMI5E*HgRd~21^s^PwfD9DY(pOV zI7yB-wccUC^)@yb2DQeJ%RPKdfXFx3_h6rc%rkF<_S(Zn+l7kI8%r^Jwjk)kz#Vq7 zTY;0_1ejxfr(ocVRWE+yLHml&Nn3&}kiddE>*u@S>)DE#cNh>kfx|}zz!Fo@M5a9; za)VZfHwl(o%MZgPLLVs z38GnpD`vT@&G?|fz`Z16OoOO4oKdn;U5zoDWg*)x!3O-(plp>}Ah0Gu9XVFcu zt9=`13Xc=N<)aaafCp6mI9XnA2NTO_oiN{+p2ol40fTYXvsWBF)Ty?9H*tU7s=bi< zo7feb_*8TA&`G=r`kX5;X`1)m^(b!RcPw2T$?N5n)9vU!#rDN1(Gu4uZo5y)&KDz|I7W*~ljz&6O~?(L-KG(_?C3(1xr~mMIXSdO;`B8Ey8rtkL&{>bf3zv& zIh%Jb!ajcb$%OJV#6B6hm+II0;M;S*ZCR?`Lk6#G zO&jRNS?!kLbGgrAj1mBuw)gggdf%k!_lNFRbIrX^rC+Odz5&TYxz`bRkJ-=_@+)Ed zD#+HLx(za~`U0&G*?B**{0aL27WKZ8CI~{8Z;BPJx!1?&<$bmhUYoRlucv4Z9Rw6B ze=3WZ6q?m-R~gR_)m-|pH0JKd17neQ?+&16ksh!EP~4!I&9x`ZBFVJ|=CEJq;3%!- z=VFV#kd+GvK&&;r6PV8`6Bg552l_WFcp1eTU{mPOehItseNGmA{C?#>Fd=2uH70(X z8>HWQ##W`TV5hvrG`ltfNo6!P9r`W%GYqmMs!KP{pEnEZq~T5jy!rd;4R(i_XVs8R z*aMwu+zHeCh~^#V48aKjmTU=oS{o7M_3L$#b0j>5_a#pvW34$8J1Tcne0H#J;G3z!e*zf76_MI-Kuq-Epo*un~rMT)1xu7I@kz(8T|b` zslJ+L_;_Pxd+!YnE!ecv;|D;mVs3S2DAnsz_F7;$oS#?Eed>IJm>2y`O&kfMDq#QH zZWL3gFwCrwN4Rgyu7dWJ^yX;RTml{%fniS3xb2+;0y+y{$_=Dv{gR$_6L~|N!Sl9e zRO}NM{HIURw_q-jzr9ENPMnO2jdI;eeKPekN3_|KQ0}>&QoPV9ty4r=rS##1e9Be}_)uOW;rMf! z-0sIsXY~+ELgyIfIudu#YaQ*Z-60E@hDpt|7ma29U$1G(RL6(?1g=J7$U9(piL15s z^&srHnjzZx<`nCcSJE@6lo!{A@-FRdKX;yH@nS@eQq0LIKQj^f*q5q9u&Z4h*~)>f zhiXrk;(RJy?q+XgJ74R?VQMlrkm_?0yda3dVDoTT9haZdWkY6y3#l2c&ytuyfPF!s zYa?&!Pdj6#R1p7js7lQoFj()^AqctOwo$FDid>Tq-xH;9EpEVtu9<~&M|r55!dL7k zpOKo=D}8f6k=p74RWnT+(&W84K@vb0ZuK4a=d#HyjFh*D54n_jC^nLD4Fx^6Igzs1 zlYP#b7kwN&YHm<3w?gb%`N?4u!6h2RJIp{$DiTh<_vJ#n4`$Pen%+Wo)Mm&I?lJnV zKZYFD5=^~O*@D>}n-|xfcl*~htEQ?x8ZN?id3d~ClWtAvxL_pGVMm$TLX}krpi^7&H8S3+>e*)b%isqxUlsWZ@z@u4aAg5 zJG(T~j|oWLeS0|X^`nR7nSoasNf>eM281SOs+C8%kQmtGNBj6lJ%y_2joR9ah=#%e zF;-d%1VY%OMK${EWYoGS+DyC+BP4wyTGc?!R85pI#yrQ@>zlLGhw|$4Xp_z9wwY}; zIZ3(@Ft3KcVC|V$zFgv$o5Zr1q>4EET*fq949he=@ShhiMr-CJYx{0ap0SI@xi<` zdhQhRO!Vhd8uwJ)s|?kFsbo_5e2K3*iCg+-ZEQ~ii2r=F`bxHabuN>n-285AqQp>o zm>C|Dfm(hJ^zRJyfdXF&$`QmsPBM?bPdfiP;I)KPib7WfZn|4O)isf+Wn&<7{nv2C zl9pbnh7EVV+sG^wHlZKe!cwcOl%h98+-#AVrWzGpFuy3vnCT%iwW7&_RP7AA8)PQ|do{pqaZa2kRD)+-1E# z9dtq%1ROs;DIC8 zCVLJIi({|u*rV197O?VKqK0$WM}ArJvny^+(rl-J7f2ZIFo(<$NC$f38%>p<;-tB4gCHSxnn9zlCWqYU-G8`#Bn0%DN%v~R3mXXV%iFDA7KVTRaA&q^pL;Ma zcn^Ir*9D_@VE0zFN$Jah$E9)l=wk?PXOM!}{b#xblpFh<>*@-!`;H3_Dz0I~Ly8Ip z$rz@B4F)UA#lVEV;C02r-Z$Ja8mn^b;aWd%ZJ5Kld~CEQUe$P<+Vj101xC z-zAQv&)kXtVbQEKjR)2XA^Nv$^=yINzBLq$Om=4^Sz(QJ21yD`FdyeqoIW;-AFy)& zby&iIvSqjymE5CUeeo$Y20VQ^4@otefZ_wD3vPcipL4*)rKwENlFLWcD-COG%3O3y ztyWa%X5%88-0;ZU%>h9Adj(?PIm^?emQ(V_^X_PB_U1+MO;F__x4_~)+%hY%)49Uo zK`FlAvohT;fp6oz`n$)0b6nCtJA4%!Gc|)(N#^!Wc{@LsysFC_^=Z_`b~NY~_jYiK zac&_j&`#~xT!}NMK`wR;o;h|K@8)gNR-muH{P4_$U(K>z9yzI(G|hMPQEL!71#hjb z4DMVAxQ$Iwc#1s&DdfB(lH5BbP_t~gKTkis?z)x6+Q*t8J?Zz+j}19bR9oNx7c6mM?zU*xI?nIeA?))6lIPgzYdrGUW^He*0o$d1~1KQZThyo;5BSH+B&M{gp2ime3_hj{s0=+By!Pfdj3vA z2$u-w224*N->ExYtVTmV-NNp^F@0BVwsAeTW?X!4U9e~tr-%v6Z7lPn` z##1D7j|vxA7>(@Na$BoMqjP8cG&x;*RyzI`eO`|jiP{FGkY3Ho54ZMTOF3uXGV|soo|z4=bzxOb)h{PR+dwG&t+D7xBi&Zd zw;~Kz9%+-;@B3it(fO{0&$NHNH5#3AA_8GGwu)ZBi!i4H;w5)5c*yejV)qsWdsT0c z$noCq{~M)%J9P2vQKNM?M-_pNfN{AtbDVS>3WTo5FI{H71%686Q?Llan}Cf?lbU{9 zZlW^myib{t!AnX9zbS@2s3;hwq(soRUPjTyTCI_Ptt&w2#bfEZ9WJ-pgn{D@qE9@YH z+g_Sy_*e)r-=mKhE%|h? z#NUG3=y(fl%%mYiuAXYFKDIFHqH}SWL6=%8LOXW9-m2X!oF%?=U1+Buq^Cm4TuNS# zjk}e7Dj!fw67Cz>=MKCM5r8^52F$$wm>1dz3qg=S=5c=OgAY@OG-$Hk9rWC8m3r@e z3HUTGdw{4&SbEkvhj$^*sM$0`V6HUP$;&j%wD-d0AZz_1pFP24c=uUF5Z4-cal}Ke zxbwl&X+_kBuMaBjd$-%{?kL^vod$u;>o3j((;3hgoVIN%r0S&9UO&IhIIUK9$5x}g z5SFESA(dO|%494d;6oc8-M!*Y>QX>?nJBwREy3!a$ zXzrgQ2zkOBz_b0%LJ06Laertd{w4>X>hj3MBIjQ1oCEsth+DMQD{)v5e?!<4R<)$ipSI?Hmd(44FP3vu6 z@o-)r32z;aj7z7at;dRtA4ccD7*OVD*4uW#h3ovs6gcoa?wpq$u*7rEMfCJ*LJtrzhH$gqXZ{~# z-jb&1ct3t1r)mdrd!CT!R6m&ewT?&??LWi*zBnx{uMf#2%Y_I z3&L9^*s~s*$Q9snS>bo7Br69)dUK4z|AKY(=M~9EJ5|k@dI3NBO?0rIyAVK{7he4G z>u4oZkYBOyHdp2--Uf#TafR-kk(!-)0|nM;MV_H;ivQLAcfVuxUQNfL0s{DMs1~JK z>c@FA{`2QL-KTOM9k-sPwz2+M1=}?vJ9S6dd_E+CIyvyJ!3Lz_1nNI05AghVc7?EX zvoDnjZ&sHuTuwb<`CRv?M^>fv^U5k-gklpcQbzT1ro5s5)fL&Cn^kv_%|DkZDQh1r zt;$Uwb5i0K{x#o0_`M830kO$)=vbHC^5O5O9Xn_`2>pr1W;K;>PjKmQ)>DY!fSN{` z+&Q0oODmd+q<^TFcQ9+|q#?7XrTw?_XfM;_?bz9G&{ahh?Wm31= zV?D&oFrT8A^?4l_YO~hw0q5zAa=%-EEyqNnsKsy((x))MT5zBKg)hcPf==3$93oBv zB>N4_&^OhA%CX$ zpA8*Y6}z}CtY&}SxU)I{9Fh?YKszqC@d~kDrzXFxrRw$l--|D!uFDT44cYak#IEIU z1~7*rjT zt7{khV)&*dkdKK_|L2fy7_sHZ~yP*2otX?|9w>c zem8XA4jZ62RC+!gpzzG}Y?7^Dq5kDYnZjq-Hk=j$^C59j_Md6;hrwjQV)(OR|7)H& z>uqv;B+LQdPkBjt+at9@n`biO-nw1SGoz8ib zLj2ljwl=|KII73{Y7Wvf{(=X4CRMa*cU+iiF|d(z|2p2zB2DP*Tt#`a>$+^s2H>hn zHghEtud};#yDT%0)BoCyjqhlLF4W6`_QJEszT>-JeCDt8Xy|9twX+re8Amf2Y%|+! z+g_(GKmI?$-g8@3t?R=ZDm^^$U6hevqwQC)Q>{vNniwPve|D!zHj)pzA3>3f)5>&-r3`uGn1iYjvq@>3u ze_dCE^Euo%`nRhxol^lnX)e1j?tdo^yDyvvBiFs0{1zDJ$)MNc2Au{y`uDmE1oG#K zHOgc+Fx0+vpE{?$hrvJ_5HIs|WpI;u^w7e-$Z%O(uv;%DH}}j=IiDvpRbl?OumLW$ zK##g?z5oGkoeHK8L*f3V>#Ia)oFm%TCHdI-dU zeZQvB&h$f(8+QNCD`q)QIYTF$R{rkppeh*O!zRMrxoU*pbJ1phc^s$G?5;xSpGe-j zyETpY-3vdS-!pqZ+}a@1{=Y8a|KtCB+bLtx7H)Ta@!4M&?;I>|XG7u(DIPN@KKgPM zYzMUh?{ag(-{&$DcU>1h`9C9{-^no?9(il9LyfL;y+BsB8kO3HUy=Xm)v{97+JmeG z#m05vb;v8#-Ss+L?p_sbGoqj1OpNt|oR#j7ETy2$|Ls@LFf@j9ExMtk?ks{DUtg-q zbG`h}OMSO+W&uj3s=MHI=1gL}@479;%h+J=X5I?{AUXmJW46m<78}DNd>1VBAU`pt2aQp}eM^KbQJU z%$TG#Uyf1hcLnh)1o~a~uZq=5`tK=_9o0-C5;FUn!DSl@Kqi4Hf@6PX$jp?y9ee*# zY9#q-YS??L&RH0C`pQ`sQo+aSt**8D%;Zk2&RSFyv2Zvpo6pK1vw z+J)-BKQEg42~+&5e9RWOjHSG3KB~{@>SDSuiUS%sQP9J28gP|g^_3T%in}J_u3O~g zozWh<4I#_d-}+hA$(Le{+gLyG>hY(tC4uRO(B<3toqR|AL{|&F;?T z{27bk1PVI(E&9d$a&Wsz6AE%kcAE|U;13WRa3tq-CtJn-^Q0*~vspNZ7sl;XT15{< z9nY#lG1EC7ZG;Ag*y6Xh|M|v?fO=Ri|4JPfc$TlG0|n9x1tUMzXeB8U^_Q11+YC_| zD>;>HRSPn{)cUT?7MVsbTj+v&K>4%zZicgpq8ja7s!!eMy1VzEI**OI3+Vr}^9x?2 zGWaW;^-q0|l(NN1_V1!08*iw$wv`g>2({{M7kI>OGO5Cot zfT?574AkZyT@VXQz+AqhNUw4I_H3QDOz~b`d(%>99fy~0;Va3n+HU=KiByV-|9)N$ z)N65>>r)^JZ<#@v>=sT&dhp#2OPVn^X3b68yy*vXTctjQH|RZ8y9M3NiK@^L<7*hj z-AEEwinr3|lk2NoE)@nOURy=Q^tn!V^QL0lI4B2{ET~-R1HOgGW=|mc#ASVNhAS2~z!nJPqRVxDt=|=A5F)7%tqP5)Nhi(04kqU(>XwkA~$ZSA@=tENb*!-?wv*dy(@yKLNB z=Y&Om`hepdKt}LB<}1&cz0*T;fe!KJhJ9bA+znN!201jUD2!l*By`hw3DWEPy#vhA zPNWVyWhglzIHBYJy8?*rT(}f#U@{!9(1U!9@L{94qyf97P-~|@g!zTDL&*Uav?}Po zOV~oy{nDJFTx~#r1SeCP zx5inw4t?jcq$ybfGdY>>V`V6|xOwTvx={XqEs%d&9*yoXkR%A4qZ!iom**>RxT-t8 z-2&^}6^B%<=Z-iRy8Xyav};8d2L05Tslb${$o5W^x5?1~(muOc?|s56Ai^*fk;wyN zjA$JyTi0OTxkBZ8?NUG=?25#9QBcYbc^Vp{H*Wq`*N|!V`TuhiK&Al1g#0)P{%rrp zCCmX*eLIz}ABg85eAki$5?bAl(t(etu_o_-B!YvcdKzdx6!ZnY~GJPRq$6# zYtQZb-YB+mi-y-9dOu;UPexf7r$@Ba&->8)bjpTsR?an@G`1AANSbw3WDhZ9z^*pB zyv0vxpb@-&B_n-%C)433IFIVKKbUW#(O~^=jYwElOFBoN^0#|^us$Jr2$Z_gV78zp zprY~L(U#H{{B{Pbg@ZjVjP^GNAGPnV%4e&(cEOPz`>DKFg{N?L2e1y{^knVRf*Y*v6=;Omz=G>s73jy{Z5T2dM2Xf)?<*@qSKk3Mr^@5wq9i$IUhRpb~S`5ySte=+ubfOvP7zL ze!#@d>#QRHC2EG6uYqvw?fO%wpXA#dyUYQa$Awq|@oeM$Zqj2qI@;|eXXCFTl+M;s zx}SYpA7!8A17Q3xVnaH4=tXTH9zRXV_8V$xKo@=Jy=6h#$H#>@vm(kOX zALLJds+<2zklTEru4AJG74^zrf4wPstbrHrcFA|rduoblc}S%63|9(0q>sXcXmBfP zDXMY)zU<_)%}GDnHw;=!a}sEf_0;r5b?`^!gMa!kZJ*IeFX|O<_j|A}jFp?c;HRzC zbc#&IMB+%?O{?VAx$*OLXM;;N_2|~*)dI}@G6U)%6;v~W6(POfWPQtsBlT3e^LoX- zvSV~zHB!W9MO8tGR|s7#W@O;D@yRqmOO!J`KroV9hd{8RX5SC+E1u$KrSC2umw9$Y z@J2lvz85G+hek$8qRZ#3spmV?P)zg#p4TIYV8|%1$C7$rqg%kSB5zpj zcTdWqR`_<}U|4~r_?_898q@e0bs5_XAO6`1A9OUr>ZkQ#qZTtSU=!#7!W_3yV6%gC zYuZ?WVQ;j~yn&y=$jASqrrwuYCMidi zfMlpiWH7||(P{GUp<8|)tV-adX2jtc`xCUz;5q;*3fGQ@vC`Z-XTeu=uLMR!WixY1 zH>dr_(Q9ooQo#pZK%LB*Q4MYq?A2qWsTPaxi;yYYlYIBy^D8^Pa?NcpQiQKOgX@#= zoaoku-^K9K@2v)KQBl9@&vA)vSmeyU!HvJXb2+hE$?3J;efs@dM(LB32GM#Q^R`<- z0>QR8=@7?^eF5E#mf@F;NtcVtoep}@(pjasho+;M->+9a^U*^N=j~KMuU7!tsCS>C z)BWqQK=q8HusRQs4_<%HP8;@IPiKYdCvg^!2{lIxtKAV`=A!}2VDF&uTg2$#MupVX zZ7)@m_BOV1h1#)bra9#}9@lQ5b7V&U{WrHDxg(Yq#+*i`fxwH@{%~FubLKh|_(NLt z-gK2Ep4#TnqjP|`>P_t%JI-0Fo5d3vN+I>mT`SRD?Xe^P%6qaJk?m%@)%#md(0CXV z*W>KE?z;@+)4cP>T0g~94|L(@t9>i>ROh=0AJCSDD<;kpi(CgpY5xI0&nL=H~*cksA_8W+XF~8?6HnmHm@E6RU?)h1{)CwhzE^^5-_9mXRtE8`>-V3wf`$M1L><=bC2kp03 zF!AmaOs->hdq~NW7Cx8@Wfg>G1g7o(yb&{@AhK0%xCM?!$|@gaYR<#txzJrPI}LJ_ zcf!(e+_YF4*TA=Ph+2cf!VpgrywUiaBR|&XM!i(_WnKMzv*9@(829JfE=GY>EPs-z zvM!$Mx#wf^Ma0r+k5z<0Q$PZzH0q`{>gzzXMmRoGd$-R68s1!Mq#|X2X#d(6C%2Ym z(vJL!JA)#d__)`qtfl-*kO}OgBQP8 z)O_?)4jkT(lIq;7ZUUjub;_CJqa+eDm?jS{7?C0OjAJ*Jizy58sK+YSAnDu5rHUC} zx#}y?&!o@jENn%sbh|Oz?aO}@gPZ}J?atm>d1K_QToLL7=I)A(@wNh8-td$&pX*nV zB(p|yljz?wY<%Xio5>9(={=I!Tle|2&1*rOWjcjE+pJf{D z`ssUw5Z$bNjxuzI&s3~tp>rY|ColEL3~!TF_Vdoqpy%|e`6-&U|JJ*+VkDXSjRyf> zuk}5Y2mE$-b<;M8P~%KK7O2Le#j~r?Z5KS9`>15D;4;Gc4AVnp=R1xwHYqEQ$2?oT zEV4weJRedNDt4CH%gTj0#yMj<2Mj-OCI>`4?C@7!Svf>@ z`V@@EiH@H#KHPW-CbmAi(zv&USh{?96{Qf3@bmUI9gOn$tyW51^=s=pBw*;mG*r;y zJR16(^`7Sv&O-dyz$lc~Lnr>1#Ih=;9<=OU(tP?hFt+AQqm2P{e6PVFlP*c#M{h~{ zXd$ud_JGPc_1SB$Zuv#7l>{$v)zSd$%wm+hscus=n=c?VH?sa&~hJ>4^qnOH4RS24BN> zR=0BRD-@R3Zs~AQUisGHOpQ`zV#Y0-2wyL^yCTQ?7dzB66=p&b?}&hopMf8U8K2;1 z{(f?RR!~8b=(flDnOkSJzuT&&`Yo6Ly>RnBn5?g$++1h)ZQi^|vU&>TDD5|LES>ex zmA>zttNAPEzlDfy=i3m{SuXfU+ZV=`<1*~hK(XS-V|#l8D_Xv6vmxnrbq@JMebtdmt^0GXZ7 z&;H0?(=Nokzb3V8iy7uJL4`aIBzo2anExlWkWcvwax0$t1N7+>k(h&;2Hl-tDCY)6E@9esbWV|{AO@+JSqxR}v zw*dsHV8u%68Fb+d_%NV-`6h5mi!bRJDGf1bcA-P%C~77}`eegCuxwswFR#&&ub8^A z+j)?#S=_SvOSW6b6N{dhRQn}}v)j(nq|l64*@Rl@-`ssW|JI3mi^7(6|NF?XjgbSf zea5~Ai^!Pxk85^k8}ein-vuCA3mn^)TmZP7!qYmP)kMhsXaAZ{101{C8#ZBExOUnL~8|Nk(-WD4_ z6Wn9FSSg31o%MR|`x_2}z}{zOQhhEk&UlhMxyPb@JH4uPl`oe>#P(L(O-Cw>TlF-g zMK?|}rUPNKL)g}T=cqIcI_KkhKb9J~hNBu%h1%4qvHo{Z%M4$q*=`a2Yw%Gz%&x_@ zB?5ieXoJ$vfeY8bj2n#uZ#cwZOZqqYWKxmZZLI z!?u?_XVXIAR#7(X7zSO)S$q?s0ek&3eUupq&hqDSahTtw z>#cL@&2WOb8@(O_h<+ag*K7Ly+Ac2joniie{gKx%IxZ>4y`7l@V?MQmt%x_Fe|F_Y zjoq_v!K$p=duIN5!9FB@D*ax-uXEG#y}9#_`(bCX@m#E)ArgFwNR1)-3a<0GkzLmi zR|31a^Jv}cIeKIs(hS(H97sRHZvCwMnSkdz*GaoLd58bp_ zk&_De>yt4pw9s$NTNoc6kNc#y%UI*SQ>z zdrG!@Eq%gu?r<5qqS8)&SB+o-rfajfRPu7>lB@hSfSY@ky*^Ll(K*_QL~aaT^aQe7 zzU|*{2qKI3OHO2@O|AZwv}x{@9nW^7a6)eoeYjc89+?2b!Ony6crB%hyY+2Y z?)TQ+>-cN8kLgxw-nX39-vSrvgX^bMS*LlpC4WC<7YqAXa-($FFG-WG)IWTB$7oe) z!{2N*(H(==KxVqnVeV8O9|rhNACMzUySMFicU-QHA_LXY0qq2a^+;#W2=T>M4<#QX zPn72$%=EEfeQHxc9)CsO>>MobB0u}Pw?9~!pIG|%G4gNOQ?O`R`TEXAd__90H1m88 zSRa^+;;dQgSPM{~K6Lr;X;RS;&=n?O@4V z)|k!m4Mf2Eq^Qhp({CxVvsr3epT|chADFdMwT6_~InWV-aK*J(&+LH9&*z`N zLz7ww!Ja%?1i747S``}TWqmla^BB^kgPDio{9iy|b~l?F@xl==`EsmQF_jYvcu zd5~nLsC;QvO!R$Y>ThP-Mf1;*i?lB9VWj3B`yz)vpS?2cr9=B1yzYG{-9TP3~J zck&@0^vx^kp6)TMbE;X|SKk!4SPY3|P6tt%`O{4QRFJO@q3;ZcZu(g)wRuRco|gcW z`B$dAM}Luq}vCXX5e1NSwZD(CEZ_L@6Qn0+$I(Arb&rk<>seUC}hD=n=gCwRC_^~{`A8zoXH*7LTB_MZh&zsGR`E}tV`($x_Y!NB0;cQ=1>)yqw055 zZ@!66yHKYt&Mnh@JAyS^*@%oeOj7UICvnOTd@8q0?9pBul}06t)ONpX?Zyx(me8G2 z`7FU<@XIi`;0XlzCQ~5PR*I(C+hk?7HYP$XV>Tg4r($j(ul4O#CE1y4N4S1bYPlyO z#BoZe8KiPg2OYz5hZCFIn>*Djv?@45F6~8KBXhPE0J-W?eD9w{`zpBGw|f=p>8CjM zXTmBH)okLlFE_0Oxh1{Ir_fngKvR;H37H})H6I@oO+{_{y#C3}pgfEHE$b9B`LWlP zj`yfkdX*;n=eP@^{%$_Wm$^bRnM_)cNL{6-WAxH=IrwQ@`ziK1tex*FbCL%Fyfj(* z0eRXdUC680V2i;S?ep?Z-(H7)t2M9OUUWkeD_ts9(Wfx(3YFY^?=UI+7&z#=>bm1s zd`@o}6D^N>g?$1Mslu`AqKikU%@*2%Sde-buwxD z;sDeZfH*tybZNiwzB*7lb&JSDva6EdC*O`%yYx9THRuCTYd6o=%-J!BA`7o|Ll=6EPi2EdhTmclhTfQkk| zmDIU!>yKMg_JC%)uJj`a#9ACLAJ4`ohSlc+sx9rCd~fJ~8YQc0MXdbkp3B%0LP4vA zeAL_A-JB7e-AYni8AigvX33p&O^;Z*u|+e!+ws!vn{YWpa`BqTt$7w}5%*_fEkgog zePAz2c831xyMfkT{yM?Uf^4E~VWKM^e-Z9`JmPSZ@%x;_C%1wUhmbd3;3$ANixIm- z&QkJI{$7~8!`Wdb*}hKaZhL$)w&NkJL8^%Dj_JznhE-SFcEy}ro&`E9f7!X9VCG?P zeYXkwB((v~d^il`W`e;GG?AWzI`or>_-}Qt|GxdD# zkNZZ@ny6DqhS+PGoaRuhL_ezcH#NvwUBB^dWuLkF?uQ;y*u{GBw!G`!`gJvaobeUI zOFeb+Ow5^JHC1K++s#*f7-tRf1tKf*9kvnn3s=O<(fT66o{|{;#2bsYdi$<3cD1ZK z8*k`efZoFIIks^X1t8!*>V8hdQB-Eo2|m!7$U3eSD1%w2p#X2 zrA{xnrX#r;57z#C-c_Ur95^DX0euEsE_7qSH+JXVPT*?Fb)DXt7my!hiS+flzeSQg z@63h_>ewzej-%J+r4{u+66JWATQ|F_^I*^i=~GA&Kt9tyw#a#Gt%oH!)i9D;jdrz&%2`=)-D$GS%?fhU%0d>xo8;kmch zVYP9ev#JkQx$Wzh-Mc;WH^g9DuU1&~VaF+R zt1kS;jZuyqSb%zyr0C?WdgD4~hMCSIXpm9?8C+jgVa%mJU&Mi;9kZ62quFp)kmYV? zy3WBdw!=E0GUD;&iy@Z9Nwb!2^I3=2768?J zb9t>1ll!LOPc~k&;9~ksQ}%^p^DMNsWS1DWm+p2LqHRmIx_JFiUxM3aqzPEk3B)oqBRmQ%ITGwrR-eiY{zqIVd|If<}F9=Rq6jMo)pIhHzC`ST(h zsp&#*i0615%!~26R?*LuLZYZpY}3sN{tbDr>Ui`K(nqn9x|b4bK6!G;yx{PtR%(Pg z*+3C@S}^_=@0;V4+hkJx?5Mt}6&jTcRZz+I{d24PeDmbyp}b+ntW)kZm%>j0S-nQh zc_xvr2a`fveqPAFFK@lr6VHWu?8d`>HIpG_VRo&VF`s%B)^&J(#^YxZ@6VM@L21){ z==vX{bLIebF*io3mzD=lM;V}{aqYG=u!`dFB`umkoqwrt$niLkok*gi(zm3QXGJlI>(OQyzsqfulDXDsJsoOJd%%Wv2dITPEsdXQ@#RKg%Bw^L4U8PSucjaqb z{RHO9&1Fz5Ow{6yGs}#4SgrHfW3S|&hVj66IMfQq4tj3@-E?*&KX+J{h8S=WWc#!0 z4yr=#hTgMFuG=e%5eSL<-UxdE0dX4UszrRO$=}+9$lrUQlGsg-G|k^g{LHNC`%(Js z?xN;%4in-r1pM9}QXN~qYJoj5Vs7+OPeLz9k4dYlM@+ev1>~MF9o*Le9u8%{mWp-t z=5_UQb@N6JX5WP=n3d~vSDl_lm#fYEW%KO3zuBR7-GnhV<(y;s&ZRiU)QitYU2eUF z6;9ootjP^9GPiFCl~s1S3_p~-UGAWyH?Q{dzW7jzqo&5<hs1QbVWK_Z_~7?zI*P zlD~0kDH5f8zEIo1oN`oofJhGNSV)YFLpG|P2vs)9Ddp8*fxOpy4{AJraMpT+xux0t ziM+0LcPs^C@^-3y8v4EDDxUP!fWW+OlY!h52BW!>-C+=*q*#(wP565~ZueGoueX2B zYYx^_V`JkJ+Z50Zh+}BU_9(s$*5pv^yfW5PL3a7D5m6ULQC%6mavoWp}PR@HryTB{#DRJjsEcTp-SN^VqDQDTSI^lPOTKWHxdrNJHp3HCdIY)yGwr8BdTuebI(N7M`^rD&e{P{5N9LT}EI0t$)6eROKfo?T_3BP+9^P%R8yIDd8~kX^g9F=Dy#JKH(VlW~`W9e%TG^I$Z{R z$W)aYhhed=7O@W3`zljg-VV71-Ck`fuZA#&6qiMO$jj4eyW^d$-t#$;sLZz%Y)cP6 z`_?r~2r;&}&+t$XOZGI~MT=e`tGBNYUrhtv>rK!~o6HLM)FlT=-R=r|WR?YM7^7R6S$0GAfU- za9cO5H))=S8>G`V3QswEDZ7`Y+)nm4s(`NCG+*mT*Hb`wt=;>1=#4_Tw%ddXRXh%q z(ctNgIttmr0r)t&W=8FYaX zpLO<4=hhu(RHU{#km@YCE#_*ctTP!sLJfniuNL`BaEirST2@c9>3)HVTP?@IQt}S|bb?F%?L1gMrtG>d;p_G6XUiS@ZWXd|&&W4BH0`ZwNGHTB zhnjBqb2qSF@$f+BIyV3ktz@MtcT>#$xEYZxR!-k?tKnU)+6tXi9AtGGk*_zLHmlie zkSiwBmz*u6lg9jUGTMbpIfK2dwVR_3phUl8_)P!>musc7U`K-NK(W?pZ_3$TakSbV zL;^}QWPvbGc>^-%LaEDNC!Nl>`sNN7*W_Kw4&enp<_^y;-|MS7gHP3igZ~{G|Ez0% zIcV(doB8;&_P#v%=or6G4fmn)5y6^Ls}U8-#Xgm73cIIA8@)U3rm(fvmR_UbpNh7D zAGPH$;4huBrWJim&kWBZGp(?~V}`Ml9&jL|i!63K8@3w1z$4Ei#Z~z#;wQ8mz@8I% z2NHAZF=WG|G~^2mL8&nd_n{{RA6MMZ;BLWoB|mSZ?7NvHMQ@zdm z^g|$gRlR0$J<`>mRdf1x74=6T0FDQHDc6e-TQvFX&*_)**BEg#u}{Q)KW=NN zjHpkb+F;?#f-ztM$$ytUxg7yDg5Q%WNX2}y%eJh&W?Effq*RA%yH-KVip=<sYmF#Eq~fW(PgG{M zg5c{xl|)=jRuaPZIBoabJzg2Xg5Dkdvpe~5X8+urVWqGfUt^pozfzN)g=RR_8Ek)2 z0$1b7a}``BrTRk-^a+U8{LV#>*q&2(fP7xxf~Qh zVRRjGH9OwDmT!;AB z#c@<@Cr3iNHW>J-j+wp(B!;ur?_s;bTr0g!JJ)s^W?G|jPYfZ6M-ih^$C#RQS2FWr zCqfC9A#*Ln#$WQnRCj*ZD`*h?g4gWSgjCnho4%qR{wwo2jdAIbX2bm>_g$BKi0DH$uudxY@2^``=9OhnS&yI0~)85NcEOevAObU5^*KT)?3BPTW4hz$0g2OcGzOa z`?;)_hsS#6ix<&}RyAQ9>0T)ltG$9ZBemDqjmp776uq$H)?9{BPs55VH0S4&buF;F z&8r(M;8+R^&fze@bJI8MDW3g`h+Tt4+G{eU<-MVm%=o_#yrrpE0HqK-rnQFH6Y<2# z2`-Row0ZJKZ!+Z%ehp>SNYJ@=W7{ljipv~zE4)&t%oPW4=6buK2)ZY4k2s!W9h!b% z$f6LYE5_|-zj|;S-I4fOF&2-2M9?`y)`1wpESs^BXrPj%MxCJw=XUwByv&0pR@D=_E$2DO%|^ zJ=}ght6{m$%Sq2*;Li-fFEIle*tk>%o1tDxr_<%`y!yNr0rHd5o5jmJj9mC)^Im3H zZ` zwzJBx=?|-v8lKoj>%Txa|M(!^){5^iml$T+!m}(@c7E&GuuW`9bUH)5kyJ}c9|)BD z9p>)3)-=^xm*u0MtINv{eJFe`eJpAV*`iVfT*E(@TQ?~Vvn+}cTm&@<6 z-%>xpyOhr02OtJD+P{}35d$;pT5XnVySA8t&ttP+g*6sDc@xRKo%iFlX+ zy~8KWI#WJ}$^0M9(_hlhpDL*Qzi3sU z)jb@XWJ~7QS52(V+U4?79PQ@a@?U8fVXaQiDd%v{QOI_8dsGGiDAqLF)1kNW( zAcKM{Z}?8Wr>k^sIUyGb z#peEb+5+a(cuF;8QV3U*LMac<)y?lc$P-X4Mcv!`2R@YV@yesq{3P|LBp3Njb-T7dU+3bq>#o#h;Fk4MukQ@Ss}JrP^Cs z3u~IsQ3jeV?isvt8T=nFwrT3e3@v|6hgrX^`(EH$O92~+#ZgsMyXhDG_Ht~=HWrn} zJ6RW(5V^FN=C}PtHa*#;cK6!r7p*tT=2l_DP%C{7rQHG3{fr>%A^bvZU&K%I|$McdYj%KmSS!Te{xB?J$>aWD|pW~*#8ei<+sE$LrX{{*lH3YhTOih{D z<@uJy+((&$&fn_BhwkCEe9OMmejTw4sIIxa0W>VEz=u5**SkK1gSlKs%f9e5ugl_@y|9km+_HF`h zqVsgwznbsUhW|+SZfcz_G`Y=m?2C3unN0v)i~0qu&DOab!inVJlB?gd+<_*kF(gL3 z=H~1=voMHn2Gz;#^Q(mgrA~cb9IIZ%60QR_o~GPhO`9CNsJd!>7%?{BmA6<@xy>j z(gbpr_=uAmRk``$<587JVGS%A3hq3Ih!8<`x3v`Zb39~6Ou4w6^bZwicG(P=R#^iu zxp_XgQ08|hkBLrAyL-rviE^__FPc_D_rKXi-@|IrsomB~n~y50kfDZD^w8AvLmm2? z!S>n^J1Hndb94>q=Awe6#;kO%J?o$8ku(#xCM7p@a z=Z&%pV*$% z+er_huDc!o5%_SLZv#Ed^!p|LI=`H^;xz#=es8`94M);aZq5d|G>O^^_IMqn)qdYI znfO-HAUc4j?_xyW7S^bT4%c6#yO31cRMv(S99kRU25X`&IYmpS$@2QGFN}r_;vh#+(UXQ?`#8v64Xb$ zf7c0X;6ubSd*$Q{(>9%~^jF;5RpA#0G1yw#d6{}Q{Rj|}KAMHLHQ!2Y-slN+8Tf6M z%#ZhOwR)@glPun7b9I}#{@CcXjwtzJB|J#o_HhY))E50JI=c~*Ny@C^mojNvI z)xCW_)21jlJMu;feJbrn%k@qCa@TMz+Wj-SF>3`-~X`+N-7ndvD!*i~cB z;;;&8YHHL(N9K1@L|~LMpjyZcC0l&5yG>iY!Mc4ZpEy1z^!E?_o6DM4@an;8bTOPt z=B5@F5VstZE+M9}5VljgwD4l(QUp?QJIu^ohboPd@cy_K(bi5z+~OHQ?wQfH0idC- z*QhM-@7@5yVKn~;mX1c5>v#9t?K9X46q2L+PQ!#HQkQr>jgb9yF_Wk63nKg@$^(N> z(?969SexkU(~*RH=wStv%DQaZbdd7$tVNluIQ@f77-O#A6LW zb2e{+hb{51%-z2gWjf3B-91@fRPSiqgviZOLn$;Q@1578K$%e=sOy@VE$3WW2LB_O zVBvA^Sd(yycSz1@5tz6jXDk@H<~Q`-?vW6oG?Q{u#FDYIxUfFj<=pjg|60MCH7m>O zEdw$uh>Z8`T>Wki60b0|e!4U5hA^%Io9Ngbr_|f_o*;B}r}q7&-RxzFUMQWHv6qYU znwoV$&=?to^^!I6Wa{$z=o8{FzK{O&f#cJp#2=LywlsOG2auM=Ui zojw-2J-P<%8}|WG?rTIR?1yv3Db!!T99>Cpdd)as`Rv(pkI|Twy~_ALtWe6c4|47p zhi4~#oq@p^F<*QKk$f$HT!MZMSD#YMYneNF2v5@&QXk5S>B)AMpBkxF;8szStxm0s z`Tt-3sA}IJH)Hej#I(iifbeP#eDu2;7BBKcJM?|T1E&xzf@FDgTQ(iLH_fD6z0 z)xsO%p`JXf6LM{!;+yDu-eXQDJ)W_lN0-`ny}7J=!&WELK*ztwG%I-GU8OU5Qgb+E zpsZ*WuXkz0ez7ahM-g!QKN`o|7ly$TE@(6kSQ6&8U_0!TD^uC>6|dMuBJTwv6D3m{ z<>*b<8Vx>;?Q^UM4l7v`j``0gRHVPl#bw=D2eZ@h^ja39%RYliyvez9S zx+~@qGeQe{h!fkzQr}j0>!`=3tLk*MCI0Izao1}5xgzt~d>@lm)iV5;qGwG~qxh&eTC4ccvgUF;FTkp4`XGUB6oNNb7Kh4vA8}HZe`28v$ zK81c(i9$Wh*tO((#E1VVN7J5rJwk-|9>t*hga9Xv zYMu4UZ%Uga4arBQF4h}j`H$;qbIg{aKdw955ta*2A7K zydVLIy~cS?EBVirAD6b-m#ChHS6~^p|<2+d7vPvw?9XZGsK^O40^Rw%$3Jy02*xb9xc)9+ka?>0<|ywS*<4RE_{ zL|HkyX0n~vgI?yS!n<_9#8)fUbt!^OudAXyEk-@=qLSLX!9p-S8O;Ly_gPn)0z;*I z!d_`x*Q<-!UONgE@Xtcpxh8&wS*bjIhwMCvD||WL--k>i z?ao_b`I_}F4)gqwp1SW3wL)!WZrbbp@HN7E*XAUe(a~X+->d^AKKI_>w2Ov`cPh-} z!D#lm7oOhnPGk)A@NXTvQr772o1NX~VKHnxfuJmzqoL`>ul{{(dv$I18QCD77rH_5 zGA_B^_apHfbuI1ZsDaY205RBt;76}`)C+>w@Z8hSHTY9~{V_)isnPlSkI0Jn4eK4| z*g^`dQcKu+udaM4i>uo&S{5hWdqlJ_&toqQV#GskBQ2J{)h7*+^atG=JLPB`hgh&CVfO`jBT= z15sA@K4+w_-61~RBJoT!4+R%-YGAcSg0o=TOmSLQZe!l1V=DPg1!hetonAIt943(~ z)t_vv%EN#EF3ny~pfXUzl8<{FX#X?#trsu9mNrN$OfAyQ-b!jf3ux~b)qice{R16nP)2nx;N3oLH?8d z^#;VzzFnK1o<>ln;ugOqmg^Y@=?#l-^T{buuY^UZyT8JRZO9o^J_n@A6%pfA=vM&= zdD-cW(RZP3$ffa^YKqC%N~ds`yF_&xH-+_3sJukBeZ%k={LV5eG;Yhpyj)R~Q(}Z| za5xhbZHZmh?=Pl6EIk}$Lo)hL)6mtvBX7EfCN0N^Zn4u?;)BD8)lH4+g_#_Mo!|WN zF-~xU9G?4pPlk^>Ug^7;nSlhCKX=b`yYLo_0L+UN>70}fe|*iqo;R7z`KM0^Zl2oo zua~!z9lpo9zHqjkjk7ON&%2_Z6eRPKFBuiVq&!Fp2Jx7&r`TAUeVwv=&YRg0kl6Bl zg&$0}dasyLT;;IQ{<&92Ak!5lLYO|NF7Z-Px!w?7Wtgr1dY02A3s}2fb~{7YvH-MVB&WB?Qn7NTgrzsU^z$4KxXTYp zG{{%2`dTg58kowa+zlCjdAoqR*yEdvuQ`45U^h~61^66R4bQu0X51_9?P%cU-e`f# zXs{3I{dH#J+hAS2ZSACD?pby7g)|3sglLy-`0?2-_c(Qr+Gt))WJm9al5dS$b!UXG zy~mdFO+gTt&LP+Dspqo~cZA-by?d=a_3{Sd(Jsa1rhVu)_qA*aM7tUc zp6uJr{P*Bl2Hs?qj3G;IIX~yRxkIVagakD@uypN0HJja}alG@uU{~fVYtY=?VZe~? z>I+SU2nzDAQ~r?87mB0H+LxB{k}R6eceL_hcd6vY$F3WEJDu#ReRuG*3rAJ`bG?5u zcefC%q8jK$r`}udkUH}7M>&QNhShiMpv)8IGQ20PA8ETWR0EkFk=8xxx3(g*p0jp+ zj#l&bUv1x?q9a9{=xo@vzVkT073;gw&I1K?X4E?KzyVhx`3FA>sa(0<9fDPAMV7&; z?(z0dukr8w8>d9l96v$_y4@REFg=M$gq@8B!L`8ODwU7i7&6Oqb<2*KeNpZL*1c7Y zM@X5OJ*v1nz2{OI`JG!?qOf)HpKnGQHY=z1Fyz!~UB5|9H0`*+l-j3ZGwc=4cr}dF z=S=63Y-vlEx_S2d@0ksE*`&T$VMr@3gOGaCtKCPKM|=*BYW!GuO|r}(GwqIIm~54i z7d;3E+^7IDJl`}gkN+zDfNB3I%iET;M#Md&&L{7TU;OnBWxJBO^t?h}Xz;#h>$~3X ztDzqQz^@-3#YLskCKBoswzw-{`bTdU=HKPhJ=?4?N%?lRR*a7$Vy5GKC;z$V;T)eG zG6&F(&w829yOpiT%ue5IYA^AH6(97Y+=%JxjqKCH{v&{&aPn9M`Sjv&(qZ)ZRP^12 znk%K`nLB4n+u4GOd;5_x*AaU#r`U)Sf8e_7^QBGZLynDeFAQ@MaWO{T3XosrM4x!QbcjpMJW)6>mO; z^g3V#sT8CHMi_Ulp1;^_?NfiOYHrlKh(!Acz(c*iR?-?n4y%MBcNXnmzVa?VH*n~P83=4FY2^7Mo}v)}J$1iShTb}3l<*J@$O_(%S}ud5}j`+jcK zLo!-!c<6~?S-SW=H{x#3+Vx9cHp1ju(C<~A+j-5tiiI|Ftj8Isk^T%b{~Abkry2Dl z)wy%*PK_}dXP6dJp8H{LMZDlE=m@VX>?>Zc{U9_iIz2@Jm9 zQ`^{@@(4W z_4jdu{d@a;B8pt_mvyCzMz8Ab%nz`%(>*_D0f zVm!Sj!4P^`V4<2RaTuKjMiei`H)J;b^Tz&p1?cQ?Q~JhQaSDo&!nW9)4sY_(R};Fq zo1ags`Fy(^9Q|`aK1tz}UeVcldCgyIdHD%!GH?fHlPUN>YRR=ltt+bYNxpHt`%gLj z*SrKO#yg5WevfJxVDYG(NEhk_Yt@9yhO5l@vTgRLS0-K1G4UED-bk3VfQiaW{4+#0 zYP-3Ap2`1ohU#ywY@cR!Qm3LW=pBn4xnF+ua^@lN3b&c`!M>aYH3Ta>PE25V>+wVs}HwnNn=oi zxn4a0DPe!E-8+1BdAj`U_f+Ee$Fs1zMO=7Z@ELz%h^G)gka~t|9iP?i{~XfYkE9fD zL=nk8IkzPmD}jdk)>}6}<=Np!-`Gb@u5cKGK!`@qPqwK!1?H5_%&t45%+EmmWATUW z_WSFIm3<_CA$i)y|7pnon#7FU=IZlpnWt9znc+h5C9O&U-N>}bX^T75OGYG~PG~!7 zGw=VNNsFH<`h+=6V|qSf8)=)@!s2yYzp#&<^<34KS1rZ|SG*>n_g-`To;YLxZr1NT zswUvT=~UO`oTOj}K;&3c{iI*STuLlge{r?ofbWiNWHC(X9!j9+9@ zQxr@pLkk)Q^5xjmqb2c^CpRxYY2G2l}T?o`JW!*@1lI35G`grQ5+q4jg;EF zryy0MJ{iFxxZvLSNN9ZE+Egv%Q>_D#E@Dhx)bN$E%cp>R5XLu z9{$;zUHtFM@XmWaTbf5O7Pz>%igRL*UZfT?0P^6&cD9gT$I)?a2{5Jwa`p>|Fj~y3 zq|tTH`o{Z>|Eq$^{o+-59`fzH+6b#seRO8uC*5;Fg=tKZ!7DJvnMn}pPivKH{?pt4Db>og!fR@I_cpn>yMRp? zZMSFd(@-lcRl|7sK`|HL-BY>i#dIv&RvqZis*P*sIcJKKF@gsXHt<*LtR}+-;nV$h zG?`O2EfHH`rA8uFankk2_0r+!P*VK5ba}omFS4z%2g?#)&XT_|Kyin@1~`7r1N22P)8R7ISXBRP0s{ zz`@?9?y=OO&nv%O@Og1tz{NtbHGr$b9CWWd;TP5ytry>fV**#h*g=*5x}E)~F|-CG z-e%^i*?(;xvr%DUWX86I2B2L(JFOLVY>w;x;6Pm}FQzi~>{|!Jtyg`&PT;U2mQR8B zeYm7;Z65FXK4<)nTy@8;232GHf4{+dvW2*2$P3ol-?&9% zc6W&Hymjn@nYq4*=gYC!Z2orxJ)PO-hTV|2Kp%-e*BQ#;?g zeDK|gbJ)fEbh}Q6Y$e})J;1_MfOpgmU1l}1{;-#$@e@aT#=M`a;VG{+8*yd0Z?xh2 z7qy&z3*-ND(ooj?iEb8U{B2O>PgL7BE!o7J^_A{*=h$uS%|ar>#lfiHiJGi|P>K}m zq)KoFfpcM5G&#-pd@H2qSygFYFM=AS$0OU_{FriDu-p6O-#LTPs>OaDtse94VQQh7 z97LZ7=iL11;nc+155n^HfjzSlL4%NGS(>k|kZhpdj%qA5$t7MITiN#Z7#dInZ|*}x zD-J*&w1*_P+|vE`%16`#r?{qh+XC`f$$iD+I&aTv$5(l{YAxjhKD*7g{HEXgGTBAH zdrq*GMIi`XE`Zs&SoXiU$xWpW193E8Ockc0){CJR*g*wDB^Z?$Eg}sLI%*+)x9_mm zEv;s=k$WJn^pxtdsPlo`Vs?Uj>ThoyYg}ylD+Lpli#UNW@fL4nJtDaGXa6j&|E!5v zv2^iYt_a%hc+)iQSI-lZ3f-REDaRQ~+4p|HN$R1M9nLp$d3mi|?wiALW>kl-zHqQF z(Mx>1*7MrF0D0B4uGMA=EER{9fWDMgL~aC#07u03x#b4rcNgl?0&YHvG>FJ0FEwGMBrx4buW)mA6!fV7iaIUb(5uG+`YDIcHx zHecA$JR;ct|C5A$eA|=MCc284S~cpp#qmy&m+qt$w!f=xo034+MWnxUWi?^Jd@j_; zE22NKhKh0$VAn&k^V@-DwJI!hZXrk0BvXHuYdO7e!5Zf1dUNPfczR}=YqNc-+evm& ze>m4&7lEb1IvpDtvok7RhyrE08voKK2qZ9Bm6=WsQvXC6oRwLn=0wXKTIn@%cMti- zGRn};DTf&+7G{O)%*SdSzmR?ad~?We8dracx~n{qncqKFi_bc>QuB95dISITSBr<> zd)63IPjs=a@|Q_tH#k#B`L&p{XpWp#OOV?)O4sgf69$hP2FJlPzFMw>^uMF}iziSf zZ+}5UJput}k9a}sfK}OVHzGEBtc<7AGPOV@`Ebd# z+5QnQ#4tLcnONz7LrpVyH7@C0(w0sIYQ1Gd;uLiN>a{2#qF3=SmWDO^*SIbqAu{T0v&7V7KZJiIj(N`HO`| z+eSx1-UX}=`$l+jUId_u#7?-9dMoF#>)lb*CXsXRt^j5{3M-Rqyu0dk&a4opQ~9tf z0b>wN!~Zm%Og)ffycRdC>vCPtBZOFeN6UKMBOYHk}f6eu?<-T+zE=he6-VA&;eCE1bYTQBI% z+k*>KR*ZbGT7x=yNF$w>h9wGl$WpYgm%8%wecGn>>2!VVE5xGm3$q0{1V<19A5$In z1)|DTgv9c@fSOOKlBqmRaY4Vvc`(rAVEkUm9l=Oxw9?h>p7{om2a_E#LslV<{?APp zZGTbaX!gzeD6w$}V-8=XWau9^6NKeV&{&r~Tp@mMBo_n7liJ$2d183vNqy%onRc`v zk!X;m>z1>T<;#dQ*ZB5Q2(8boz3(mF^}%qJY^zgU9sXzcURu6P2gWgzhkloL6MOh- zqvL1yIw|%1>b_a7GxdAMoE?RHyH7MFMp-bafE*K_HU5aHK_T+PYF5QRGnN}9dBYZ^M+vjUSpBl zb!I7$*2nr_EC5G)EK-N|je+yxDB0i3%ak>I@r)htxSTqPOLT_4;-w#FhWN+muHK8O z*dVjN(Xls|vT31pBdNA_OaS+|ef)I~zGjj)&3S!iRV78;&>S&Pds_K$vS?cA4uj%~ zvLM9>+74)8&DrYIJg-|Y#+}q4{btR~e>R=59>vDFyokAva4GC^`>hMD{@^mY)sMM( zib2}kUtM6s>P1+^E#naAg>Z>|8k9pXoMfDi4^swt+{PA=?4vEdPTa&;-`=<0_hHNF zmVOXnS?OoKRzZ{984{80<9Oqv3lEt*c*31edo!+%F&cpkoZ0l@7J zw4r0}IRQS+hwY|bJx%~vK7kAyA3yJ6d)+9{^AjSOv9r^jV-Yz64vWF4FPXQgc=}nV z$*W42ck3X9jOm4>N}Iq2{VBY4RbUx@-iOV|=^{C!H-e-V9De>k3!YwkH3SM8Ab@X( za3&wQYA=+J_l##6r?Wijf(P6w0#ZSi$ey$5Syp4Yt4I6b56=$ywB3GnvIQkweYjqc z3-vNeBp*l3YCYhx?%Zb0Ya2Qlb-y0cg?W%oL);iE;pAE3nr#Gv5oH-N#EMN}u{lPI z(*`>pfAhz*eik=yAn$o_>}2-NqVUL9J6?V)0O17KmGRMSPCt9^EHokFU3=%s4XrG7 zx6jjlxnh{nYD%EzeY=dD`D5cG3NR3t?Z$%@@A|=9q}f<+o?c@6UHwI|YE{IvpB74Y>Jmf(jIMSU`XJ1G+(CR)0m8{ej zc=R?(a&4+MZ^~qED&X?>^M&#nmLAB2{v7qMA}J0pYGkMO=7P>=BF$8aS=;SZGh-~u zjn(O$+MDe1io{4;vpp;L4TqWRpJRJbP6G=`f)3eaf&5a@AoD z%i>>i<;iysrqQPsl`4`JXQt&{#u6&ETIKTU^b0(}VYx>4VNuYtb7;JTG`fP*M#brB zRvON#;dW%#KhOHMhf_KjBj;kvZA3$ZZ(yIf$j=lQFd;S4dJ606@xE7O7bCme*DHWP z?~g>4Z_1INZ->K)Jt?@)i?g1%BW5$wgVqg(KyPqN?ZuPOv(Jm_gU+ITYE*n*)9z3R zh{9^tjaItqy8bd_hRtAqs*cUf>@{fF>h{jGQrL!P6m)(3ocmY(b|7FC*oW44iB#9{ zv@>115Eth2ysdto>ce-Zidc+Z-DS$9GXw38`JAig@9|Z=7iM0z8-D_DQ#!%Bwo7VH zBG-5cg6^gLOEo`;yPJ3O`)cm3!*{Ye>89JVix&s5+@K#n2oaU7_30R60{ zfON@o@z{dW&YZ2YnJpu+bO8B?^DHEVMzbw99`K{XALkwJ;iZAQLh#Q4S(fhI^J~oa z?;dw7^d9@#gYBH$@>Cv_%9A;M0byl+p#Abg^~HGA;=AmAx;Q-`Z>nwyjh#{;7d-zi<&9c9e;6Rx(Oc5eBRDqKmbNE^__H;FPi5!+1co%`;jAg5~J>H4(={w|I5xA?Qrz!Hqp|&*wnhUW^#NC_LJJ0`~I^|g3rJZK@E%Uoo~~xzS%jkX|+($ zuS3Mjo=a4aun=ZH7`?O3W+usdwLPlVpOq(gFQa2=j`+=Tm*&o&XC5b*MpgeJiSuEk z8-=>})z_M(*pjSQ7K{FR;bbH?OEz54$PMe(HMoc2x>xB?yMeNasmA?zP-0?xePZgk8f`2cU*NAiUw(nSpF+VST_n6_XTxP`R=crm)R_G# zkH@`vQb#N}_*;n#H1nBBpf6!LVk+i8wQYOzDBvR<>EaE2un~aNcYE>c;r!F3+FA+v#Gwo-kIcXa}Ya^-bt_b5HwU@Q*_uWbII&kkFBl$)2RM)f?5 z$*iVozRRMY=KN3`vXC5Wtz7mao}Yzyy~fk+Dfd94_w>{-gDJxT3Y$-toXS_;`G!+C z5&4vT4)ki}9wBm2Z4Sx8uU6%T!G1KzO5I|m`1s!bGdpBZ;ht}l&5wVBw91z68rG7f z3x~OJw^IS;Y+t>zDvBc-(Vp@4xp<_q=?UL(p{%{h=2?FBg;yBlu!N8 zrqZl6&-AN&3TacSL4C^~e5y-#k(17wvt?U7ldxEg|kMP}x*>PKB_ z@74OV#e61jtPO_~hEAL|56mFE!xmt(Id2xzqgqnei$lT94$mL_G}L3PMWD-yGy-S- zqCHxz38U4YeQ?r0g@N4p_tkUl$ER|6qnGp>NVinou6}m_P6Lz2f^9RfHrge8IzCrC z!h2UIqlM8K15oM_uG?h%GSy&!lg0Br+sQDGJE}I)jsOzIqtjDLr`Mm?vBs@--II^B z*z77vr8f@D0rjPqyib3mg%_sTr-Sy)k^5AxNPTv8ho{f{G*{@J^JORKeJ8o|WBb-0 zK*SBlkUpA>%FnOKCOVkXA)aV;NDk_}BbeMO*^D!rieIg@X@ctyckS7t_l)+3-B@Ui z963olpKX|x&TK>)Wf=G)e!?Dqx~iN)-lCuTZhusalert}N?$pWTMaY%&yI1u5Lt%U zKXO#27MDS;h6||WTj>7!(9Ac>*5ir-*2bw^zM=-Bt>;4pnoFu`O>ehd&skJ&C$QDU zKbU03jQLDQ;~>cF>babH?GIrQ<@m;Z9BkkH0X;km%C=F#&P#6L_v#0e9^Q8UC6?i{ zpT~GIv-1i}rNSWT$G3`Mv`YQV)b9}>N64)G!g=)SV@9K`v}P6byQ-^eoqwFN0Vut) zIm^7^dwVggu0S%4aLu1o99#;Ql^_k1`1VjZVR`8c@IqwP$PQs!UEI2uFmY(%WVtv&z4N^o z4q!qiD=#5~s}9+hSNlN^1nsv>>=q|t#gW$SWV$YX_x)LfG(K`Q6LrpgW%pruWJi$k z@fe)Sx+uXd-oQ(fztN?I8zrPrsq zmlxK(J30&+{iK9P(<##Vm7u%hFWXs*EAYh~eH&W@NTpm6yXICC`4+tUO9S%04-Bz9 zw{EY}9kjI7ak4-ceD8P;s)LGS%~KBjn`<)T#vX?3JNTO;6hj#fz_bun=>l zM>7WL(&V<(wIJ%iwq;d0en7TI^>$03ZhJNi7Sf)}>^6(e;r*c$^!R?j05<+kYBDk2 zR%e0N?cKYdXj3_6OQlS%3Nb?=mv%tiln0-^)n+XIHXtfB9ZtGuxUpC;>@V88r&k(6 zYzpPK?#6MNO!Ar*Zvf$GrYy2T3RP|} zc=rYV8gPn#`-5YyA0`kbYZqzz?df(EU)iUNnSErRzEvZFJ=HN=X06-2gk3&RmpD`F zbzGz|UOmy46I+P{MLsw7h!igVM22cAM2f%3asB+;+3Er?Jy$$%joE z(WhO8YnZMxGTaTQTF2|kN6i}GPENFS1ZijxmDt(!moJ#SMEh$0((Lq4j*C7^8Cia& zm8$!~=rhpmcxACucN6V5#qspestz!m4Ju${FmYu$0D8)%*nfLf2rAOHDaSE@Cii{OxYABV}92d-Q&1 zP?2NdY8|T;|MC)~WGu#@-o$*+%^9e7iKsKmUA^2eMuYqVu&IWv_2{5T91LQ< zDa+$(y-}zt;E+DP?VwObkKei5VApGouCGrAiP(_pN$FyVz?~{Y@lMY6C0_U;3;Cl( z+@P15?Uk0H(&2?wpaM8$CzElpBxhNwP=WMIScj#X34tD2L&Sbuuea^jgD8{cU)vBq1Uupf^Rh~Or`;okvf>J2mKOCytDi^{W zZ$dt-Pt>}{qdD_Uy=;scFbC>u7?l`)=4w9-conebHDjOL-v@X-op>csFZw_vdo> zE$ndi_cxg7B-OS86dKumKm1>r)o}u5& z=wrYz&YStSfn}z%fSS5<%1(LTUR^3`a%t5HW<_keKHL&d58+OJh;QNQvum#{Jw;w$ zd0nrJy4zhH;MMGfu_H`!fPXm8%)50gMGhEC;%jtPPx;{1{+z-0AHT#Dty>H~N*6c2 zWuphy;z#Sde`>U*@sjFpX5T6t>7Un4N8%SN8S_Nm-G}qy6!(gK|LVH&=u^pYX<=0l z7Y-yOFT3q%TIk9wk~H3B4CPb#49nd+$UD9jh(>Yun{DHn^9y&a@Vf4+pFc%bx8yJ$ zi_t1PnO9of+_tNnX*Q-;NfFI-gP^ZfadnL`$mTn#`a3y~wLlh6h6ien)6zFvhlX5# zhlg)3NcSw!q50h$oex*TPNQ~o>U~3!`{=Hc%Ovkjd?fZzU8eLZ**4`M?Q#s#d$!RQqq~T3d+Q$zg=;;}ZQ}cCr{A|B%`OZE+^^|rO zK$TLLY~ggj-Y0v$a;;-cQ-&epL*6~8=ZYBFXZ~KKV$fYK*HNF!Kw}|$adcC*!&`5u z5m%?ybVp-)JU`T;0Hkm!HpIHbW}D4B@eDHTth#i%N%e3wyMx*WEqN1&?jASadj8QF zOeat2{o8co%H{gwQn&wH5w#?^TKoPT0 zMy3@%@2^h7J@qL{N~W`#IJLos8K*7(+E{09O=ph@i{UNxWnoDO);M)SA;)UxLu6EM za_)Ek{1pLT%ov67{xCS67(UkaL^c08pwp_pfF%1_6LXSpdr1k@TLfXD@;pjqa1U{s z4iN!HnK((4g6=^+X_t;HR?_^22Z{RCG0($7QHi5phv9>Dd5$QBTfa$;2tb1$9EHix z#NPhZxxA~H#u|Iq$8$=~qSCt6uZnU}%iDXKdb~3ikD;OZ?+H!&ayl`!G5)^fr8}dI zmt~;E5+VYPtozDwmC8mre%spI#kl?WLP@~8KjSHq3`BeLHJZqFVq%+F^D}-z*7R@M zoel5ea(K8C7mH}Tb0tsdCuc_!ZnsQB^G8cL=KG!R0|2VPcjsa_2>VUZFEcd(leEq} zuYQhktKFW@kL5ZRQQpU0j z;FL>V&LH|&3H_Y${Y!!#cx|f58!hf3$ZCG3N^ZyI>x1Yrs6o=G-Q&#nFmRcQeawTU zzp2e}uv3GEDnoQ3@t+ul2QdUZjutRP=Wf2I+$=sX%ondPz1I+9c3Ee#`Pc?mn&!TPNn&60XDH?5?5IdG;}N}N8XFL5Q5-`IjG9R@ZGbcCcIDwfD#5tAT{KN2 zQ$5L|$*GO-a%ECfD?I-an={SV)+nBHhka|h0=b@I6R*;U>HCEEJ0BpAY+W?-rZE#& z5Kb1$BH1VBGilE(=lE961o!9s*6EHWAU}ajeD`S07WsUJX?myIwt=Rt>nYJX=l6(k zyW11$cFg6+%&Ct8V1Q+|Gyc}8KGI*_EVLq3E8_R!2-?-_a2CC?E}6@bp$_|VKWF{g z`!5+g`lfvX@RK*r7mc}7`)w=c?osbInEB`k?{ab{xy&*<_ur*3dk;iAt7vm{K^%pD zO8aeasz%HWQde$l^>8SX+hY>6BiJHur~$@>-}rt4PYt~ihGLxxXiPA=@qMba?-}L0 zyq|+FrOmj4yeit~%-1)Xx7NjLeqkNDuf9u zpm;g%z8rIuvQjg>-@Bvvdh|N z5v7-+B7O{&jut`KIv_uyT)3b1zs7^AiDr+GJ6?kuZ_m|QQe<1buqc(cA2eYPtaEhN z_esSn7oIs1pIh5MCDimqjD%UGqd#U6`pOo%YWrTt)ks-xgzw~;?#O+f-QT@|zo-M| zk4EQWwSEq(xnTL8b+C&=fJ!SwX9B+cYpv7Gki?`m7%akU2Z6?>wvpS(Jm@@$9WhQL ze?O7v1KKR{f!=o=`|vu2H`^D1NSCL5$(C9)Ve~-5=hQl8SnmOkaqgRzrCxsC10F&+ zeih!pK~*55`YB^oRocZR#Efq=_Qk4;?Ne3x*?}5ov~{rFevuAF+B)izH6&nXkl((@ z?uPkY$<9ujA*5s!&l8WoFKu&n=6XA&lXRV(cl8MwTiZKrPvXx)D-Y=F7N;Y4;sb@i zIq+rhfo+^|slFKXY-Ez$o85>eQm{|b*6fV$F1xYmUS}u#tZevxa_|be-S1YUJWe04 zSEKaDq??*syB7rj6=YT*Q!8j9&VRM=Epb6)Bgky#+vh1E56=*oQ6_thejcvyjCORw_E0i zg2#2AG_(5A4^VJqc6W6%gyZp`&&J8KMjhL=`)XR5A9Fr{mK%v_CE35vobvV5hBX#( zHq0wA?^S`X>ly5X@{=s_V5?hQIP;sYf^OmCCTwA-c!)ExnyEjKr^=?W*AH*N3fmB) z+bkqqdM9Z$3qovfl?Z|j{mCVMx!@g%O7Cv&8`)7CZU|{_d^Fe0#-;NWbOx}lq3V}c ze5CYkxxHyr2G(QXXd$bA)0F(aUjUpt%=-Jr?>r>y4Q}slilqwqErjcF>#$rH5CGev zsWXu+5aW_x$EUmB+0KF6?|wc1>SWe(dyO*q3aW1e=vcj~y*9plg|mnaa0j;*TU?e# zvO{M_IgpaKQF2MGxcC<=q&5}oDx*w*1t0pkyFeGS*>|jDUw0yUu&;}Be_9laMh%@W z4Fdx6-x>@w$SXHKkhM|&u#HdI)92UEHx^h9ruZcSJA4k{xuSPqv00QKE^;?twT`!E zrIEY9RfvCK@)deykDTZvo`d2zdRAtS=7cWK-8NaQ#WA&!WHH$D)_0WsVF28;^!)tvC4v=|@gu`uND1q`4m zF*jZN8jTkZo3$sQlc*#|7MRg*Mm6)BeH%xyxv`MPQ4F%s1lVZSZ@B|P))ruEZh4Ct zsPMaO__ZV+?@3sp`M7M9n_~mg-RSMFAS>9c5`Y^k0$SNUWggTW^yPkv(Z#H69%{B= z31(%YSE@&tBn3idxJjE*q1lsc6TKaQKo8^Lx!eC|sv9b!6Xs>M{p}c2qwZi2lcPKo zHM>HNd#}vy^<0{Fmz}WNCLT4|i`NQzQ43I~TmpBOD9?++Y4`t#d$(pqwQXDXef^3= z#Vc}Al#7arDBu;vyP$%Ch;k8i$3E-f{PtaYj+}eUJ=ctLVx5;WA|o=hk1pA1K%=!< zOZke2U$mDSwMOS_(c9*^JmRKB?h{lir<$3yI-)&%3Efex9ZAxv`Z*vx(IC?tHr$=k zIhoTA+#YL|%pt4t^TVUQo189v($%Uny^;G&%}NWWE%46u^7WAYij~%dpsLGsh)64~ zc#^|i^Qye_cV6-BrlRJxH;56SEjaB0n-CVq;>`#uKup@nK?Yfvl*ArA4RNH!-+AqJvw_w1nTU|*m zI#HPZVc+X_PiAN>u+R3i%d7W8poze)Zs2o2^V?6c^7WB7>JZ;Y@w}+gMg3fxv{d>F zm`D}JYp*Svx3We%H?>w?Bb86(ALlnd)Eb}eZBPtbB4{aeBl?yKMpELAJ!Mfj-*56f zKGdr1xE`gjcOTi>xH3tD_pI2B%<2%+jrMeyc(s!b=?i4eb!$TwOp_Ruor`0(w=1-m z83aT1cy4=z0?3u*iAw&_>F$YVIMU`?s(p*c#o^N9uh96IWveIrVoSGm>t>{~kczbs zjO}dPDYO=^yS-Mc`{r;qT9ObND zE7xv!c_Tg`H|cR8u-c?i@~+UsmZJWEMr^e@Czxu zqy4pVF3PP}Ir<)oTl{51ghCr#V3K*LjqM~C1NeGd4)Fnnrs<<^YV(&p;I*zzR9woYTRwVxWJ)8$0ptzjKv5cRe&vgiad&DeC}?pK@D>HKj}asQB; zj=^v4pD}-Lv2i(*x@Q)l-RT63Ro+|Y-PAenpZ0o`4R;?1DwLEp0Cx@L*q@#&DLiw( zm0OUIISx}+S@*kXFAb~ynmPtZaObYo#O-lCm|gdGh=NWH8t2J6mE-8^p~Sckh-5m- zEs&sPMk72^BT1kW$;1WBmemr~bq@~PODbB`lY0+{<&Jsgi0 z3mpIqo4$ZPjj2%>Ao$@tJ84v-U0Ms)+z7v_j`!n zefF5VY|g#o8HRYp)dhh7_IZw7;wG(1p(=xPQ-KTJ8DxJj5Im z0L;5Q)Z=kTPjAUSvIXkrTR< zBqjyhjACX_PuXqRt#U#3=& zP_kw(We#e6pO4>VO5~84Pm;rz>dyf2k@a%xDcYOeH(V_)r)FRMJb-9A*0D~`Y`wCk z;-)1e{9|($pflf@Pl8MUQI_M)1hVCU3S`LjF} zi4T3-u`3#V0)>&cdoyw)y(Ay1rt;_>YZ@_qvFios`X{@mF_oOemd>LT#T=R)cL8zHs*CuPqa|_jE zKluD?XA*m2?@Xhk2GqO@o(;1zZFh&Mk9_Nn3b=C8dXC{YDvPn?Q5Nn_M`ipz6?a!V zLtY>Y^|47M=_*VK<|ju*=+%edvCjl}YvXoj(jW7EhMpx(wC*`FQ)6OuKRmhovUzSE zmGx$Bw6&OQ_cZ=Ju`kYwuaB10qtAl3<&~+^Lec0zR0i$$a93{#VSjyFMqQ^#1@EqY zmPvbDl3m4dL}xt8sH#B4^VfGw-{al6EdfH>v^@8;xPI}+e!3Sovt6-+wifep6I<*o zj(Bl1uB)WB+1{p&%~n!-GS2b9(v;TPS2_&tH3$_TEA!l7|Caqm9B1cN;q@G~@1?mh|y443A3>^rcI-XLvuSIq65IWlxLU&=Ame0eh~mKfAJRP5Rg z#9-2=9c1{Pvt3!v_Xl6?L`BFmcSW<}IBEHx^+N&Fr!u>YEJjZkD+b3S+8zNc|GW9- zH>xVduUp`HtAR*Ocb#h!LjRO;RM#$<1$(Gg_RA;K3GvjS2V1RlYK<&PON-l#rTiN= zktX64sBFV%WJqLs)pzrc*Bf~C4AaQAitX)wcC$aM>@=Md23Ko0+wkb#j--?i4!;EJ zDU!C~8zzv_o;9mG3A!oeyGySEso5^Dp=YMGhhKZjWF8`p6%SdR2lgwR-r^-_sHfFR zl&PdHIO9XP&d=UbZBDVx!#6>{5IPaE)5T*rAL&^?BUDKvxH=hP+#)U%K5C_YtS+5SIzTKO5Y_5G7 ziU2li)zr5jQA_#XBq&-EZP|wL{aac)gMg*LDy4~Tkar$)Lg$z42y`b zmPIq}W>qhd#w$s_nY((=uvokGrJQ49oGMM_R$<?GmU-#ini*s#)E^ zllr{CT3p%LMCR$$i@Q2)6cMJR*Ww|(jZ+t(BX&Mou5vv-G;=}mFVvkXDazKXpt4pU z^>1UwDrloUDXt5-L7YXDmQ$_y?=qtpy)scNP0Gin@50)Mym0Syr=e7XWq}V1_~a}> zje*BUWOaNiGV4=QFW-}1bSH=F;q+^&|O&k>xNxQO5TA4GSqK^fw?lms(+BkpDi^&fY4| zcc(tzcXH}XXWyAe_Hl`Gtq;goEB3yxw)5(CBupIY4EtkseYCTT^fOdAB%Sb+*CT8CYJ95R9G2nQkw-RLWvr5ddWIdb9WD zdcZ!&)pxOiclNaH45$~&Z?%%q)dkRt9|pJLahEPC`RdAvPK}g;)0u47(lAfTU_&WU zmSPo@3!y5FSZmhaMv8x1KUjsIX6{S+vn|azk_KP~aisW1NjyjG8#ccV`dyDd3^6Eq z>etCIs>?+_tN^?l!i-yoFlFS82A_6ZuykIUxl>_&ORoL&3RKlY9VhGsUp-EVNh5(& znwP8-7yO9nEL)2Yn3N%)M3CBt@{akI3=DJ}D{-vxd$zZc+I1(5XQM9B27^vdIFF9! z_t$+t5LV+Sv&-Y&?3b7fidDMaC(hvZqg8k)9~|QWH4&~?6CS7L?FUQynB`UdZ#&K0 z7J4%;YJTw_4(@6So-+MBgfN!JA!oD_8U46;h2=bZ+IWKyy8Tq5Vs~iq;GWW8uv$sP zf4$s3%wJX&AXuUFH*KGL#$SVs_9nOFN` zXm0aTw&AG#);TqA`t##@zrUUK44@&1xP~ppE@KQqFVj|sLV-}vW@CpOv!|j|cx0?8 zy0jNJ@EyzAOuFteM^|!PPkxxxEX1l?qB@Wk)v7$!#mhku0>zCU-8nUy3vqq8Ip~G_ zpe&O@*{{;ns$uho(QtatX}WeQU=i4~2yEY=PaPe~ql1%fz2n~CsZ5|Bz$693ilPV8 z(|Ny=fw*XPZS$i4@$W!*C?CtG=jW!!uS#BMkE3KUYB+Izb@qypw4gX&8rlXpsyc&7 zWM`9s&NS5+I`s}pp2`)->n(|5gNgRUXVhOFt-_*(CkcqKqAll+!sbXlrE0}#-_q9# zE>;#R@DW_P*u0N?QiXHw{XF5Pc-ZO;Y0hMtQ@~YcyIXYqx<&G_<^Ihz`0G}oKaWR= ze^*lvDUajiaM$bi+0|)442QEZ^h|dS0(0Lny_MNBqN2HJC&*YyFzIg&mDDK{Xy(Zt zENfS3c%4PFuEb7rx%*yL&q8;{IM&zaz_=|ei^%1IxgA%@b@F80dhhLQa8$J^$OpeT zK(CONtt@LyWl&02&r`tCLt5Ruwi!cW)UI~Lh~081<#OyJTQycki3g3~EyKhEJ$2v+ z09U75qHEOHW`3EQKD(*)1Y%iPTeL52;!t@mrF7=m@bCBhx3(^=iqb=|l^=;TTQ34M z<+6BFK}9{jAc}Q!SU%6rw$q`+6jf-NGv@ONA(|JP)SeJy+!X+wl9*Vc7-eRevB4 zG$hsY0F(Yqo9R@$AM6_(C2DvSN-{wG z2e)NtdwI~Fh;`bPPcuwE@Xh+f6i$jaZ*TJD#0GmlYU;2w{D$)Aa3dRFcDN%AAPnbT z!nF=RL2o^PG-DOXI$`IXK+V$M_aU$?F>XKxn^;+BBBTAZ`u7{>k9@fklT{*7-biIP zoOL1g<>MD76X!CYw7pnrd)}!u$!5Un(&k!INSrHfptW`CyozJsbg{@!&BN@1I8xFU zySTAaK})aBK8kq%mfBqkd)~k_8U*@Kr;TcxEA8g~pk6oP^}{>wMnO_}Zur&UILW{1 z`(E_gNvd(LR-W_j_FnDFfD{N^QGMLctIBy?yDcd%{(^2T6{(j8o8OYK1+Cso$z;j$ zhuHc)1|weGoh*pxSxM=ZS~#Jp&LRV5o|RqeVjXAHw2A9^FQN^z#&L2o|FmwZ?csY`1oG-ms&^wGyVUfB4KuVhy$@E>`eCicQWi`b-C(EP3!E2`P!?8&yGVOm$ z`Jz#2N~KmE1I^O5yQW$oFf}3F-bb(dnu0;2#XP{&JRsNE?;=NH=A)1;bAJ1e&+EtE z$az%p?^OXl^zV8AT|ekY`5tdfUS7QK`w9i9+$0POrz( z_mPEwM78H0o@2hLcN8~+JWGHs-Xctu$PEF1>Q5}`vot``{3y2a^+v)*OsA|i&UmFJ zEsnYegv;BFJhNB+Ta5{8-EXR>U9&3%K(G@p+HRQrd2=N+PW#OY^V@9w2iIWdQsY@P z>06L`TM(PK&FGcq{Bhu~$kTG&CdCh)Nh{acc22#g@7L(9DT5v&6I}nvtrEW4d$LPUZ;7# zF0?AeG97mGTxwFP7XT+e`Y9P373_Oi`i(Y#8TsrkBhSOq1GG_Lqd)3sg>vF|KS_Sy z^`==Ki@{-3ssycdBB@>2a`gMQc0! zsFDfAAV#)dh+I<~e44vj@nS>IrP=FYGtTIOe8S=h9>~${8G{i~Xly{b_B5Y;WiFA2 zMyZax*}U+6vy^#DR$mb7Gi8h!sHJf^7pbZ05JiZ9L-Iwluu$KvTYmtm7S^Hr>p{nb z)nc|p|BYJuZU0N{*TXJ6X^~r7X|VJ%jEse`6LeHa4(sp0O)Uf!<>Z%W#X<^;OfO>3 z2T<(_kI3?bt3ec*z>fOr8Vwm8=OL@4_ zdmf%Ycg=@imfk-CO5@Fz)%O_hG`~gl#rvGvXDgpawTHI2=XTc+UQ$s%rT?GroI;7( z($T`%*uZwT&g?x`=rosmv{ET|4z(3wl#kuU=CIv%e1MA%4+sQ@ytUkm>jv5ABR*e3 zINlle8eFCuyxU9V$@Cn7)UU)obXOeNz(^<5@xehooz6@a!*i+gP|r^$Z9>Sp!z>-U z_$VDOmjKz#+c~rF^ySB_MMlT^wAp8mkYIo{kIvUFmmtd2kfy|@(;nqei4fBl%RO%S zOm=AEDBDh|%rc~6yM(>=N!wxj9JHej2b{uWso;cP5- zziail-Yhn=eO@>Ob}?C{rhP)AsPL1o)8~Z^=6d3I-czffHt4`Jl_!Va{SpA zc1YLEb&tmJb^=DK(S!JRSib$`TD@mcaH#>G>9v&c@9l3+Lf={qr=xcp%|t0$$V_gj zm3aa6w?q|AmE{r@Z{Q(VK(++d&0|%1`C6)=YtW))=9mltQZ)S=9{LwCOTEwXm%A8# z|G+ALr>k7Q!?aJf)U#oKk6IO7l%xTK9u^;&Ww|zPRri0awf}(S?*eUbL)!T2AMCat zEZ+}f_4?MD)2gdQZ)3FOI)ARwAK>I)(AQbJze8)Q>vQur00mb6+=&u;2WIiCVOp5- zaQx2<{Erd(YYn{7LGb$FuTO>?oRohebqSsN0-t^4``SvQ(0C5OS&&MH^+?=Ft#TDZXj~a_I{GxjqvwB zvGjiP8A|671P0;!$DCKO_0cRw;NmOhGD9?+rUaq}V>TSI<0d}4oG zew7&WUnrZi*0}5amoWwVJ)%R9N2+XnD}P5){M^8CR+J%NM(bSGe?tm?qc*oC4tnB! zeEa^FYff78`{&PI?RT)$51;D~TG?a%%cJoJ`l>Rm9W>(p@uKU$X$O8aB9u{+>5r4s$Qb+4`5~@WF*$C=f_}Kxwth?VUGmxO-#S z!zYJScRTBL?*LAwFH4=$$?W1GCQ3O<)!I{tafEjrAu>{eUm*I8DApGO-lZFlBMwWP z9-##nnYR|UUv6OI!D;-NzJ`?qlYFXm@H@h7g8SI^(wb z{=YxUxwyWz939Ky%NrzIN7eIR|Hf_mP#RsJHRHv%lU`?P=?46}>;CU=@xd}165ky% z!85WHYiw;nUv;q6rJ=Yd=buj1`0(TB!8`ZQI0> zRQ~Dk;s*9DA1NvPeP!VA3wcP1Po53$_v$|#z6xu;ZM;9N{vHh&uoy)}&=+pVZdU%s zXmpO{$7Nys=fC`iAQ{6OzM$~ySLXGyo563jI5VDHoNW0tfm(n|><+LtY{)OFD=t#k z_vN7J(bZDsUkJ{YnanNxMt#cLuH%j{?d@B7^0Z2V7z~2W5EyLU<&k~uj!tKFcDQMp zz414B?KLxM8Aq(g`x*W#mJ*JE*Kd`wK6t&6x7$RN zD*-$~+Y#!PxHo3bSGFeF3wr?%xxSh*p&{+#1HJ4o`v@L;F07CZQcTSp|9IEU3Fa>*BQ@V!{&Rd9|wFjch@?QJp!Y9yeXQd8Smqg!`kr(Tc9`bFfPvI8J;&W+0SH@1=Yc@e+c9gpcA@7tiXyLiuS`cx?wx~xHYDwCCsZ$(O~CvUnH_c!hQwW5a@qur>61s3)Gxz69I?S!J7h#6uZxaBJMbYy6u0u59;IE%Ks6>O*0*daVa95vc zm12LVfeOqiFIq-ntW9&k6bk)Odjb6q?ztm@*Jf=~jNT=-Dl?BJmcp1+740ujg(V4) zai^Ns*NY&|j^&mtkz@dFTD}_s=)@bjq74Wi$RxgMp-<1%%q=|>s?Uuj)o!~SJ*E#}fCwnEd~vs@I1jkEXqQmyIt?t)bL zIJqP|KR73R=9vjb??GL?1guQAcN$WYqh^4-&DLg%N+f;Bm%-Y9V%RJ!!Zg(Py{M|B znrVoD7W9fE?7K>{Piq4w)gF`21zE5|bf{k9I=fXCuSA^9)}wQ~>2Ejgs=m6fwwICi z?hj5AA8XpJtC=F>1yQTDmM^wRiAFnGZIX@5oA5PPu@|Am+h;bvD=6F8q|B{hj01Y`ZB|( znUmFcOvP6I%?`p(>4^3Ajcn7d;=VE;mU3!pYRO|O*L0>EYXy}Y2yaLcl-jC8zfF&= zhrX`t$Juf7-@M{eje&j6)U_PSg5oyvX*_ihAiN?$@ zDE?epVKd;Sq#IRW`IghO{Cv439zdcvkMg}>vq?~;ge>RhN;Rm3O#(-1Qj8*7zJQiCQ~cAK$VWPgW1^yN~3~<>xv2dG^`ozAoLgjz(~Qs)$i)-PVnknejk>i4vPbu9saAVRuz7T&=Q`xwB3kO}f2N z^Sqq~L%H+aWXE*=QHGS?judJ``8F$w354~1_Hbifz71pawW}p^ioUEBE6?;0Nkpnv zU1O^m$Po#*RfJMYb46(zkQ58h+5dC@Nf2j73obzvPu~4;m)i*>-o`61O)FqkRvs02 z@fdZr#|9-aqu744|FnfkUS{`$%5z^i^9j%e@$+W)l#T}AzF+op+d-{4s}+WEG0k{W z!%1dSaX^p2y|deGVzl$caC&r%)tx?ANo%>%+)aynYZ0SI=T__r6P!azVzc+P_ABjE zZhMoHz`%p8mbSwSkOK;Nul)0B8xoz2g74I~JnDRnj(AerpR?0mMH{7gtB+DEFp1d8 z)BGmh+MivS8V^lbl${$(Q-AGS&6KFGWWcqc=z2Z~)J^*V2|5stE^Gs(B;N5y)mTsR z&aC9E*pyPS`~HI^C`C7#mL!n2%-aN2ibEZySv*e+A$Q>%3f^lZGVR=^2_MbjVm&n@lm^3joqGm!6FS zYa6TIpYzVqt9`@b?RacqQfp2utN5L1d=X$_3DjWV5z-4tqHcA%eCz`zr9iO3wJl1$ z?{fLlsotfhSTWmdDw`ZuNI$dgWRD4GzE(zR!$?`N&DYh-(ft|1z5upNcCK>#zRUAu z{WMRDCtuH_AECd2N!djFo3IdQ5Mx~iwMoD2x>$}4>J(qnlsA-6!|eed6~5_tH>8DJ zX@`M-hcn!DdSr>0cA;<|#MpW=d=0WQMG7Z$ewi)HgLQZ-o(o{IgaB%?I9Y;}_A9oN zN`3#z-=x<^1lOXufCk|Or1Nxfh4D6-OMTXr**80>G>dgLPZ1f3h=EYnWyk;r|X7+GX zEU)6xGsPMAd3mv(k7NYB-i~IeQ13`~c@oSvmv{R|B68U~K0{ci=W=@qd*8>j+pY{t zJoreHO4#sbV^RY^=T-os?nJ*Guw<$yj+%aMv3rhRRQ5rQ=uX`0N@hBPbI|SL?Dxa2 z*h&e`yz5Uo3|4d>rXADqj=OUn+4%?^Xn@%BQ7yghhEUEF&PWx}zV}pvMHfQT35ED1|UUpYg{mpSQ4RclW8ADEWVMjnGF$hm8x6w`i zgJ&V~G}E6|Ad-n%b~>O`p z@NA6)=I zcdv$z;5mIBCu39~&6+l87mt%eyHb@WpfY3;BzH@7r0cz#`*_)_AyVzi5jC**Uaum3 z6}2qlIa+Qlc6WT8R*MDpFbb8OLI%X(vM3r2){|lPn?T&nGZE9ZN5bRo_@->O!jfqr zd&1-Lo1Rc+y4&J2#)F2fmX;&~wlAw6vNz7w#g@np!4zt`AncWUmxGz#T=tNod1p1T z2r6@;8WCyigElQORhzd$;H*X8PDhf7Q8yES-$0#gcKK=R<>w>^6X@|-Hp(^aNc4K2 zuQq%*A(idqOdWQ zUaoq#-pd~J{OpZM6|a;XAz|-gctrp%_it72s zUB}r%eaTaou8dXeWnB!&`7yhqR~kdM(+TvR?p=@{X5;%i#p~oP+i6sn)l9lNVd?NBb}#rA8f^)?kkX7+@+yYvn%ycrM%$+?fj#lB+#_;K5FNypG$3kn?- zecPFLN2OhH2|*8W2T~^FO#&5^#i6q7(BPX-b!Nd{8-JeTP3Mk=n_j~koz|f@V(8Ak z+3VGxq%bYv0lhuuR(s_sRpU(e{4(2le>H!`Bi1j@aVUS*=!cy~ogSkK)@i(Jx^JXMJbfwm?QSY_Bi<9t5}qD!brS`;$=Gto z|3b8_J*pcQoTStIC?L-$Y5OGbLmWHk!OOScFr|}J%-lMq!!b{{ z#qV~OdbJ8T_6Vcz&-BW2wCB_|`eb)1Uaxh$Wx32LKb-D4=<#~XXxh1^lUH?^Cg_j? zkyYQ^KB?kd7|_K|<1nueQp43dRpneT6d1iPs}YBglUFX)!F~_tt%3v_`h&-0yaPW01Q=KNh0%T8;Ob0Fd33El3JdfzQOkF!~DvQDm6MGz#l>@*J?wJv@7W{ea&ht7rE zy61AIak)E!0QS@1QnCpkvfV2^U{NXgWj{CF_tJhmF89~<6LI)1H>Cj?!vtN0O&}R` zVu@)4kEgn-?8tKQ)#_hmevIOz+F~78G=;Mir1#QU8UZ?aq&Y{- zXuUK(4NGfmcW~P&>mc8R_ey%=WE1l@&;!&9hLYbV^!kCv>+~@*t8&2-S|jzhTtAw5 zw~)#{yf-D5A2Q7H-PT@0cM#?F9AptBE0w_(epV6K<9 znZA5X#0aPNwN?yKa=MGnzk12Nq$VQi*D1itLMrf2ohNmEvavB0g@XZLzx8eak+I@R zxuee>#D`E>$Esf4lqhd6k4%i^E}bCP!%m<5V2xCc{kLd=4neJE{W{&LXKtf>e{p$< zMPqr+v;D72k+s=#UkofYN#%F%B2t8#uhxJ7rnY=*_a8`cX;h&Iy|TyA(LW-5{orlb zTAuX4M=AHFEitn!QQk1x;d{VszIeA{hmZ-B$jxmlpBPvpO^aW zwV%5Ff^WK|z~htSVuzB!<;drGywjUC&aaUp%s&pqo8_CbSnK$)=Z{Pn6%8;!^GriY@H%PoR9H>Y&d$OkY7~i8`Z4sMTL{Qc2WEY%wEp?jy(z|)}1ry)W5fO6{nSxFqPUO^9EU88&4AY_Bd! zp=6C-xo7$8RU3pTZ3FoRd2D8U7L7K-P_M^iUbfAdtGhP@e7HeXESG@B_f7PaKULjF zkGtuvqv@x^+PY-@TI(XzTafd8#T9)<@87~2!T0)P+c%o6+}UYPX0++A#YTkyG;K~S z_bOynb6e#0s$5HQ3VIv0tpazUTAYa(Vb;5(#Wtoj2$f&L^Z<7I70p@Hf^jz!uX-rw z4X7E9nh3wQPVH846R+klz}_nXq^)@`fBM&QU+#p|_nn0F+83Ir9=S&Pev3{<@j1-- z-#yHUy;f|{;Cu<@lXELKf;!z~Fj~nE;+;Rd-qz-cW^W8aSJTWc!B<;1?Ql$(BB^o)A#STA9*?(UQqg5-OGC6AKN|1Q7$n?E2B+kQfb z{F?Na|F__T*Y_uJtl&T3Pm%5a2UY(?{`&btv-uxHFA6_S_<8@TQt;KqFJc0!OiPUZ z=dT0&o%~hfYIudI)qk-xg|jTj{xW|Nnw7w3epP-B1Rq&A@93LcocFJvBM#t*zy2Id zOQMVJeBfAwCJlZOOXq)nei3S5-5l}H@4Y|2t3L+n_n z`XT;*9KQc=XT$!}*@*WK?0vxN6vR>ZbA{PoaDzOf1lkf87zxSwANLEiXyMuo?$3{t z{9M?s-cwb!COMbr3g0t$!f5{a3tUmfx!=6cF9yb(7(3zZ&#`7et8 zJ#at6t$*#$?-BofgZyLo|8Y+coBQ?W(+pktxf*}&Y1vL;0N&2LPI+yUinBL*fp0TX z5MrrWXP--GxhZ-g2~u#b_x2|H;DYprcW zLS6-o=E?g{BrW9qNwz!LB-s9;6`D10q-@Pj4PQKBB zhZK-_jEptQq_-&F$f2yfEZV*?D>GL5QEn>&(;ycAi6H6wmK@pb;eJ=Tnn7l5427Ln z!oAyUlyQ4K08RAmy;lOxtuoG+9i{4f>|-ky6if-srHlqE#7yP*;(LezggDi;FJWJt zv^>1?PHm6PdW_XF>!x?%Kgpn2K8w4{@>ENWcBKanm6z$h-0W3{|A|!K|LT5FabCz{ zxkDEN%$~0!;B_= z?ud?)FRWwVX2i_`vUr+|=(5k8p79IIuql19KP=(gQ4M=ula@MlYcuGRrhw!hls4nD zopXcfH}D2czP(Y(fXA9)uRL|)wvFt*R?&bZ;upVis%RhGu#&H=3(~VR$uBp7*W$9= zcQa#~hT>_n9@an1u1pr;kl4*P8*yws5j4Rd|!L<&aG;xSU_EK=bpOU&| zSCyayw8eZE-Mz~*U3G^0EIJ9%*(Xtl$=!$W0c5)Vpym;3{^nIQa$J*UL{G+A=lZg% zx=ng3O3$*MY>&Nr@TqarC^$5Sz!@$Mu|cz{SMKRhX+RjqrT}r2!Z-6-Y$T%SWRTPy zR>oA|=S%0s__`pDF(@JykL0z?_7bJkz%$xoQFlm)kDy2Osxa3{rOq!bhBsHKjNr_x zCk6X7(Zx?S*L<;;>!=q)&lw8l0LHIm!Yue1r(lmpq*`Oi=x3;c2JPOiv|{unSD({j z78)v+ZZcPNSS#;S+0@`hfv<*wjn7u2XX-mL+TU;MTdkxu?wvwY2Zk+(`-^sS_La++ zVz-+P_rhfbp2lXDw)O$niAYEhL<;T0F^ktp4T!PID(bAs@C}%hLDx?~$OZYCTCdB3 z{wb$dBuwjQSh;lSS4L>_a9c?Qkowcb9KA+AL~igxox!l;OWpS%(JE>+ zTI6oi-ZWm_)7^`Xty`M&)00XMu#mGRT7D|Si!M;xYyFNku#d3mKpo=p+;I~HSJLqy z^1gjz0VtoZ)h0{&v|F>kpS6to8{smfk1kgK^rn;eI65rzeefbj^J1>HSyi)kvAU8wXZFwpq*=a(z-qjXPdomesR$`%Z5x-I6h7<3xpz!i zc_dvm->I^l?p~Enw(y|S59BeHM^qQf7VNJX1%i=WLAT{nZcRpFuX5`;-cT@ z(o8)yp)Tj+VbdQ3x?X*!KgeLPV(P{kLVLiXr1^{Do9(4~Od?qM%ZfROtFwzip|;>C(LYBVY_#RrA6cxYb^5W+Bh zXc#Z3&m)j3UrV8;npoFzN&YDoN!^miD1CvD{i~T3l^$VxR1@jL0v>a3H+&qP3^h@3WkB z7|6y`l4oSI8P+{&v>P5EHEz);x7=!<0n@(CWV`99ChF}Hox5AN@|Ko;DfjIUnMcJn ze;b=V^XUjf{9d&$U8Of?1pfLC*-8BF^5|YK`g0a=HGRl6m)Us6{)DQsII8hvyTHT4 zq2ABw-ywec!B7aVZ}V#eUSox0I=^L*k$0IDuAHf&Y zl8iS-8>7dBiL%#gXJFWhH)fBoICwl;yXdYQ@KrXS8-14j{b1ZWmNErd&Qhmpi)iy4 zu>{2L!TEca8qF$P3M{D;apnAc42A7O?1q`tS@WHlNMtnfIC8Ap{U$y}h>$7gJu!|a zw?R7Z)rjS8__&tSJa6Ui<>R_J`)RpOrWn*le$KEWc`74y?XfFRt5Iffx9@XgGP3ji zX*ZL(_ow^3Im=e|| zLxMhk%RK5WvQ@(>pSTLhk}0We@V8+8nH_pN$GL!Gzm?rkkn;m5u5*=^s@0$qG+G~h zp9Mw?e`R-8GFh44vwU@DphM(EclfA|xH2Kqep+AH;@4WZWpUkrk+u0Wa}-&q{>`{M zXe}a6_l&hjgsNT(w&_Z5?E@ZC=KWqW;grM@)dJryD?N7MDn?-{r~s6(OC^(*7H8(| z9wEbrLoc8r%7G!T)%8wittCzJq}W49p^(VrP06XkB^a;qhuOpdKAxfZE_E#WXjK99 zyE3hI%3DCE++Z!JCNJbcN3T7L9t~?&OQDp0#8$VIM+=>=>fevicm}*PM^H~zMzt4BTZ^t0>8(d~tCa|if7{s4ffBJ|(B4ks^ zdCzlC!S+;uG4V@NA1fd8E#!PV>s;{1=Zp;iO6luxa%~GKWE4zi9PB!%3PYFI&boVU z{Dd=@r0cm27x>M@sXckJ$6PHv7*{X7;7q3c-$VRjy5Xc{Z zB$@3Rq}kUgTS2+r(YdmXH$DRcTVF5ciUaR?8r_;nmdYJHPDI7^OpiEt<4Uc($R9*{ zwtm;DXLq&zjyDX28VG;>)SsnrIHdM$?pue1QNp<|eBDSR-9r{_EaUew+ZC}N3eD~S zAhUgLL>6nyX6`VGcEn-70AN!l3vW%4>Kp#&9-TfVX8^^Z%IpfiDsy|E(*af-%7ASD z-X=;Vc)s#(?^_~@uta>gAcF^2=d@HkRKiDRV!Qj=TNU4UWbdxYaCRXRC0fMP>#*mz zHGbD8ld_3PXm7At)t&QFZ2R+da|`?JA9=CdtC-Ih2@?E;0aV``6Vkan8l1tc{@9u$iVujDCi@?-sY6 zQ(y?G@77=^uGc0qDQ~SrYdOcasJvJo52${$SDNec4xeyKiwJzi`iIJF+rgFvI=;}4 zimR?9Z(vENLanW#U^4_&ZzjuoOamXgb& z)dgC=dYL*X6Y0^cosl4VYy*kMtI)Lr3kOp95b<)u{KL93%I#WSVap*1&6>a{F-Dgx ziaHaAe`@QsM7PV*_8K=cRR~<$mwbD1Z-phBEo>3P)?uz4HOfWlIIra1?qJ=(?AdJE znc$ycZodDO+~^l>PQCbyOP%u0T!=VsE#KU-|EKDHxh5bubJ}pUN;f33U+!?dI|&9) z#uM|{Ry?Oy$PUT1$Lr&^yu5QtgP^_rr#9hGC)+B#L#1DcoaO}WC&pj9F?}shp#5tI z;S4w@Z($*O>tnRJO5P~WR1bM1oUAwNWx0LrWaj79cP+OX`hB#qYgqm={gZjjCK za)R^*Bo7G82qK4!?(sUfGo$Hdtj(OX!$|)6nK`Yh8NX6Ae_rWuR^I6M0b}@RR2c8n zoPSZU`kbh__Hz)#lz5wN){m0h?4d*(JLCaj!+^Om9Ad9G+m)mW38vjq&enbs)P3pEW)Oo*14K6XyMNnh3E z!!YMu&I>|-1958W9qL!T>3e1S>_bGZ)TWLF9fGHx7S(RRi}AuFGjZ0MEDD>){D}}0 zx)J)1cP)3vbf(itm8h1&AG(393M)&^g83SBcQta0o-6w`wm@c6C2kxAlE!I}d|Cqx z|0&J=Bg!fR%0fDwN(M?1gwIt@t@k{sV{s{Qj-M7N!Z>7(Am4d3zBe{tBN5UUKP1`*5Po_$ z4`RCCLFIukg-WxYK6C9M2c)3g@cry_<^M?D^$#m;GsgB==|X)2Km{VWWVBwSmfkKzIE=QCm}Z=aZOB=Rn5)kF zhu?+;dZ#_3(+BZbbhEF# zRZZ$kZx-~e$NNDRkQph!bWg8OAf#o$qxoFwQBZ^oL9k~O}lE|E2Gm7 ztdU(E9ymaDwH>b!Pfn#(lX;@2axb@nS^DHHC6a&9+f&x@kQ(9x=U_r(6(bHuvvT8XpR&I}xJ(h)PPQ<&%@& znR~P{t)uTCxIaJ3!(K7-_KtD&a=Kl`ad9bvB90KzG5(7r6%j0$48EbcDZX|q_6XC2 zA&8vsuG$Z0Zr#tW3u0a>{6Yp{|$5d zN(;Bo+0Oui?H+APav>|MUpN5Zxd%FYa&c{pS}6>}MgSkP*T2=*pL6)uJQ!LJ^zp?-2CP6JWn)@{{1DoCP<0K) zni44WLYbck$3@k>zGmx9;bnCyKp;CcJOO>dRGRDUqgJ6m1jz)JHR1yLcff|1z@5Hf zpAgpn)TiX}%T^=%lwUwV^LdMkqOk+Hn*nY+`I?LK3 zzk8Q_=JeZ0k4t4ZIDSZ3WIFG1XPdJ+F*n0$X#;kd8<+Y1uvI8v^dmXnx5G5mXPg!z#%dgi^K;^79xSx^FX{8p}8{EbcRsMaKm1@=$s+ar>l3hP-B2Ipt zxIjmw+5f1;Uc1d5;V!H0;EMs*&Omq3M z^P<$+t+u_C-t83*5ZV^_;6lZ}3 zjsL!Ir$o$#0#gdc;MhBO60cFy`)dB;`D?y%ZPLKm^7Y|t#TCu)E!~&(^>3!nvoeK} z4ZC^QMi{U#7clOw^}W7!!0pOYv<ZpBRJ@Qh1&{5I04R~8@^negX*B=O;lu{dDEZf&6AT)&1n=; z-@5kV^=LH#xCrk^ujQC4u5)|dVil(Z2w?985oADp3~F1isQf&towz<^8cKbj;pm$r z8n*BY|I;qLMXO!OHZUp*tg%yvr12>^)mM$N6Kg7VPvlR9nsgrPWmVd9=LoE>?FX~+ zh(EdJaagi(}hkcV<<7tNlOG$UJxO;i_lAA%WU_ToTlqGWdy@&20UprL?#j{mcn!%n)#l2Rz-9bilIJ)aF zF_mlJY$}(`!AF!lOqmAwrQpkZxv+}>iWibTqy;{lQ|r7;hU0FHv>kK!95ww#iXxLR zst3E2|EIagSpCuW_$qd88i#CKGHAK+R&rP*pZ#mrO^$YF+bEs~^kMk4W~+Qd%n8fZ zz_PPXCEElmRag{(p;D+~BV_&h*4(q>bov(8?2jN*pgeEFV%It`>Yb=3&uKH+KaBM# zOX%X{g96ZeG-yXd24dxR=@=Z6wao$YlSvX{ALbkV+|5e)`M7z!-VROOeKZ&6#5&3A zc0;`ESEyJQ_O|BTzSq*YLlPV(3xSRhvpqVBNwZ|iyFv|v`n!ySv+Y&zGA7*vVvQ_8 zTx@&?DLRaDW(15Ta`*gs^kl&|WE4m~KPqTe-#k;ecm!#oP<~gdp-){uu&;Y4S)nC| z;?31wj$S+JoYyqt!a}R8%Q`V6>cn{~M@)JjmFKKj*S3&)+@1J2JOiPYm#caI*?Vm- zsAtwD^<%HJJCz6L72{TXzDnlTopUdgXZZ=l25j&WxKwRII;Ri=0ORe`qX-n2*R6{q zG$9+wTV&1pp^g88lo%lkf$Y;H@k=xW%bg&(@Rh;Z>ZfcDYXG;3$fPCe z%6f-yZ$9hZy=Q%bDVg(PbKZ4qGo9;`FO+?fKW%SPTpNL@Chk0x+-CRh*Kk~qKtx~L z4!X;8zV)LHuMP)wVu=K^2_Tyy+R*&fUCiox^d5nV0!#b-A$KV>i;gfP!NM}=EiQxl zICXNEa7gWcxBgMo{|N5wa+q8%VNhW2!KW1L4yC&IVj*GUqxfSHrhz{be00@6gD!Tu zf5!FTj6q)HX5L&q@qFoZ`Z|C|iHl>8lQK`|_20-;yW@TmPX;9n7Rw$d<@%~rt5f!cB zeR9FXTUK)$*D1diuW@Sv&UvD%%Fn~>Slxqspxan%AviF7{yvhf&yNqHDy{S)G1#;U zkRYEzSQx-C|Etr?*cEtrYYaQWf1uvnI}Wch6GAj7vbEqIA+tNyj%|Gvi#O|>?37jH z7b_x*Y|!7QRogfaUaSpt;c{{xcK&!UoC@SB6mI3O-b7Z#3ie$TGxzz^Yykp5BN4Xc zHZ;nbQ-Y?yGQdKO9xu*A<;V86Z>^d(!AE2{de_X_*k9=n`fGxiM~ED`J!! zX(Kiz?$@Zs6MNh!mHW)I$oI@aO+wSb1f{EklW=?Uup_H}?tyx$H|n`E1s6_+=j~qm4Bh}Hi%0Vz&HC{O963QJ%AC5p%3`HBre8nt%bmV@HT(4W zvfs>?pwD63@Lr5=!A~Di7ck}(Xk;{eFr(4FycpyCEfe2&nWCKe_e^IFZW%hr`3iUX z+Ns~N)3d*Ty201?ZT7UA%l9%vkG>C?Ta>92(~UqnO>U;rM>UudYccyP<5f3S1Psp{ z1mD(H6H(5^6R|!7D23`6K^b7}_3L84x4<$%pPv1^aUqEwrA^l@5Qo-vFsv=dMDbTB zI1-{`z&fjsV3ID}quXk$!O#Rd_jN9l0R`!TUjv9@yNGJNrG(PY?!y8ase_qcwHT`= z39hZI8h`n}sGGJWO=2`Xi4UJmBZ_p&;tD)>0|p}8ng^%@s5 z7f*l14IrM3a!9$%+sE$Zx2Rf`^#)*k9co!F%O%7A9>)gdM(-=~D|(uAdvaCmdEz)dHk?br{kUr4sJF zMBjPOpwsafSZIDG=y48G>+vlAZGBIfNoVf!??WegtoRUO3;y}1I^1OraFx1CLiiQB zxm(;CG?z`@08?IB^gDcKFh-ZRYZy0sW&i9~uuRk8-gBZ}r>&M7;R!p1{8BL(FnOZZ z$Nt$}t@%Q0J}Q+-A)n1FQzW-5S`G5cor}LC2P5+vEMJC2MO&@<6OT^w4P+9PC*ktd zg(M8RCB5-&<$zNkNyuI51{p4&D;R9}O3Q01%~JQ#VE*|BrPeQGXEa9KRugl1_ryf& z@nPZJR=&a>zbwa^_JX zQuR4l2Zb`5olGWqi;{Y3e4(?WyV`m6@d*qGPFjqeZ>+5EcH4S(5sVip?tZu1>F73x zuA}w6#l+7=4iZq?FWr$eZ|~FZZSGZXU}(fPOA2qJ=C+x|M!!ED9l;Y*VDZtzazDE1 zozpSin@ipB2UvWa`CwQeutOgl2jkoQ+G6`!7Yr(|d6$^D5LJy-&ZpG*pi=UBKumTT z_8>m>Q|`3)$9AQ8*`Jz(nG~j*`4Ms_{_eMJ66EJBXjQg9F-Ron%r$jHH|0QaL0w!M zqxa3G%YAB>)}(U#NpAR9q_npEh#%nH&)U$FpQj^?>K#1ip*)F`8NTkjc81FmNZUf( zD>n4VNbu7hAuLsVDse)IAI$3H@VGHr;kxeJ2&T*{9@8~|ijB`QtV3o}efJ6UE0R-! z{{LJY-%$e&^n^`n|NIqT?KQHh9Bt+_|7sn`c}$yiwloMb|LdczD@|V+L`Z3vXQ!f9`sh~8%n%F}ke4-s8Ok2^?yKof*44e{!xK_2jBppq zE^(=%&!D!H$;^6O_4!md={;>6SLsf@K3s{yN0_|2T5)*1UG`>B^djyLDVo>cGNkTK ze;1nTH!56RLuo`oG9;u!9-F&8wT2jw{B$N1^m6cc#Em^#!mou2u2`B+?QcE2m{i#N z_K9c)-7Vtz=r-Gh3hCgGY8Q8EkCGz&9%iO!VnKKIDjym!mxmGH0gvgRU=t%_Rn_Z= z+5HLAfwIqWi*t=Qeirpxl4~}Nswem7Rh~U*{ z=rtI)<3f@Y%_op)-W<^lQ0$WRApLv)B>pzRRk$|Nt#Taz_gX%3ShiyGFP zTXGWOe9uooi?cVfWHAb>?N7dofq`9F`KO{*qPml7?SPCc^A?+l>m&BPVRzDSxA{OK zU?Wwt^mxoiMW-{Kx=r`jA@_eVQo~9me^qo-XW=MZTM_t!`-y7>n@l${e>=O)yks$CpgU$jrR6dRnC2in{iYXgEP zK@&B1p5(9qI@G`eq4!>#54C3vr8Y|975B@$5_!TgaxbI7@;Nl6 z4R+>K(?@~5e7DmF%U_2F4ouw2>itMhhvpWKCN@_G>#Pn88>isf zw$o;xmASuxjx@P6UJ$kmT#)&(oOiiw@D@-m>@A~35;;O*WrHy${W5)}@#6F9)? zIlrxy(8^#;WY^YK|J@WcH&KEjbb?0v$<$^yUf)rt?qP;zatCjOY9{|ZK1{H{3TcgS zt2Q_2B?MMod3iN+Nh65EwAbAG&n(wS^e5HA8tQFV$4PB*?&;0$~oUxxVn0!bB11767&u{7ja z>yUSHPsMLL)4hkC_1P z+!e`@p}jFdgOZF?)xcibM$4`z-BqsEoG-T|{yC9v_VXHU_>AS}9Y^WS)X&EnYue!? zzxE-zrMr21z6eNpPxMyJS=dkLBIbjLq4+*<%)f0J40m4Vh-9LDtxYVQ+w#)1olEOo zYWFFXCBToq0=6hyx*#~=4l)JM@=V9q{Uz67&HGo=H8u5T-z{#KBRvh7Uas;RW)HHa zD9oyVUI9a_18j#umSvXXjRV5In;!~~@1B0Vhlgrdx(t+aAnx;9u03q)p>IKBIPqKA z>3tGGo=Be#>CY0zgWj)qtS?nV+W{SKNR513}uM{Ac@BVrLNuxL*J?icDQ3b#690sq>hdFy+ZmVVPj~GPwg=3wD>0}o?Vpr6MoX?8qPnW++I)|~sv~<bR#jd|ESjL}{5033l+ALXe*ub$B`8wd<)EkFH)gUI=<70}M;59Q}mk43L6_b%ae zh0OaIzr1djr^1*ek()8~H;YEt)#iCObn~@Zeyi@bjW3Nt?&d~*df23LEEQ{K_qq~y zjqJV7PvSfkKYD}c-)|oa@7@7kHdA?@lNJT=TsI5lV9-a)XH_$>*rwHYblu#CuYu9Ypk2%#LY2V{l5(Z<_26KL{D*O!%zEcG)d1H(L$~Yq z>aExsQ={WO*zA%D@D;Sc34_P3jdt57kV>9AlopPL$T%2$%$@Fl(XE-kVVh>ADUCev z_;BQE!q;AX6@jld|dU3|77T)2S&W2+iGTC{zkl?7cAkG^E6+oBFpDQng97pHXClhu{HU8 zP{2#anpj-x;!r59DeGL*!gQ6XKAoFi5z*^%QJM9SEx*c?_DbQh!>i|D$8|dgW456; zF+Bjpr|6?NpRg zX}Q(;iVg3aTUE!=kW`Q&F@@OYSw$I@PB+l{;-}qepHbnjh7rHj&H-p_Rp z_uH_4AKTk+l*4C@#=hct_3p0?=+aVj^{>%kJ5C`=>{D*LDNyF0A8e+N5Tj^q6g$hg1ESJJe>volV$O?z0?^Vmq0*AGHjf*rl5k?nppn7h~KAHy%`okf0jiP|~xu;aVi zOgh3j9ygSb)12(JC4cANXHAYggz2E|gDJ5?%iaHr|u9jWs>amKk$2USf?zD~YS z_e8^8{oJ@hsxm|?HuDkEs;o1=aeMGy6k1g3o#g3#=4Z#*x^>-hbTWYF&8Wu9L}|U$ zN?twhtM6fJOKpuwXf$c%bUW0;vf59{-j`?RZJ*M9K*nWFVo~(4W zYcaS*o8H+Sb#+Z|$tSkFT+RfhRqKq6;Tw2vzx_1t)3(TQ z{cQY!1BPUF+N?I%cC9;Q>Xot8F(wgDT?Ls$^E-J)gc+gS@W_q~MWCk(q!LshDkKxxC6;HA{A;bYUq?qV0=TY8} z`uj${RlH>|1N#Jm4x_`om*PEd7_gX}06(nMDNB2jRYz5q0w?VcY1xyPc^3$-c-N{T zXjy}G{0wE7kPFdd+fYM4pWUPTtz5*uILMZFb?h{LXpcu_*`5^#5W-f% z!ShQaTA@Qc=-sF@B(`o5@3`>mh44UL@!Bt&_(|dLsg~iG>LIVz?z7H}0d_J3BUqNMi65~Cj&o;+3 zT1={b9e`9DWY(ew@uo5`4~?%rCO4KDz^6_r3Ngn&rN!7 zbghj=6M86sq(T(=d6>!k=c^5CHM2Zuf*8PKJ~tKbRG&slH%hawv>0{+|8I10=&E9`7rz+YWUg{AT zl~(qt()j$Wk|&`7c+rx7>3cl1yl|^r)&r1JX-R*%oL~TF<9=_|bLC{X>P;?I!0>Zl zb!OeuKFq=ABZM>ltIca=so9w{ssek2xL@jCi=hR~j2mjq9?1p_IfG z8%-()kR&$T>KbQZ=BoZ!Lkj6yJ+yDB>hR&cj7%?R;#RrV1Z~?8CKUOxSTgKuv>ytdZl z)0PJW8j-g9MDi8?yMC$)u%!5OGJxJb>7@({wtA#K*rGym~FYwl}Lsg%@#&);AX6F;3<~)s!dz22;1#c%NmFT; z--#^Xmo{OhKXo8#=Q#YO#B~cs`BG87#$~^?W|3~i-7ijlw_3Sgcrus0=^VOIA+{zh zFdxjktydM|wm9rP4zzcJR09G2XAshI_#-}*cp&t8+3Z$8QHyd|*zXtHu>H~I3&+n#6lSQi7zm^p!N z|AQ{ykFcA-l)m(vRN{G)Eaju$jF|L;r5-kL($phm6h|BUg0VlP_xK4VKGoFG6@HVxdztkwE&b=;36P(w zv@3&$s7CWi5H5289V>)IHX(om;9SA#g-<-)_VOIPyX)5w$T;KUH?+JF7M z5aIYNY;8CvSAvM=e;!yo_uXfyTn}>@LWOj7tZ#{ar> z-SCO4b}iZuR%(Ki?csX--CqIhY`N!gnX;#4b`~Lw4Y7uc<9lhvz^xLy z+u4~kVRln0ElT)f@cJer+3e@biWqD4%eUrCGUM{9>XUgSpShqXaLxSpowLsS)$h5H zDBI#`a{ByxaZq<-h0y;Q;dESn_{{IkSd)ejuW!D;y3K&UTa@L-Qyn|M3m&kd!aa_8 ziJs)9ZwS$Sw~nhji1?j)m;Jw9?IE&+lY4G^?2V7STjhV> zwxi&@JgVddo{C|g|7vLW|Gd$M)=I|ZOOoF!%teX6hmJbYsld4xX~?*yxTcO*fY@hZF7A=)#`y?05tm!dLHRpySvNT`Lccg0rp_thva6_eBP`n8SdI|vp&8rp6o}v zWR+>noUq^1AbwPNTe!6N-+7tG<0CuMM^(Wo-1GB=UnfplJG?S@p$Z5->XQ*?8|?D$ zD~8UWV}vk?nx9ST-W$DNrTW>=mzO{<%(yh<%wAr_$+y19cLzn7x{V*${c#bT-d)HY z!t9JCcf2udD0QyGXp@ptzSHVP<#RTT9Rbs*m3qA_AduTu=Qn#j-!EwKZblwi4ji5t zEvAhVzm{Ez34YhmsuYQ&Fkn?oS(a1v~KE3-Yj&4~$F zn_hb6Qo$x#ISELqwN@1x!>js2?7oYyM6N{Z+OnPGmeZp#GD$|P8$Z?7Rab0D%3c*@dNE~eP zP_Ig(^%#x*^U8-D%>j14)UAMoj{Uq--ViEq*|YFj(wT7}`}a|)}LBpLVs zd+iGIA$Uuz-JttPGR^XnI{a`Ncs*#NTfQzc-PVW0XO+T_udUkk-;U6*CF3U9ckKf} z#o$~z$hr493;h})EnV2>d;vu;OYHslW&TSa5+x{uc|>cx_CYAKnm!(=4px#f{CbjS zdDld3FnNOMM~I)fdl_5b`q*|5Kv2h}D>Jk%abO0Nh{_BoS(|e4wjHw_3qUEbHxdh zk53@D+T}J7o;|n#wnNbb$Xgcr?FdI2(_Ku$p}HW-B0u!I?iJ)v1O|*bLR|z ze1vrFveg%R**3FlP|yA9vOVL6{nuZzuOqPEa+3EK7YvCQ(`l&6YtIHm#ak*v-7C-9 zGspwXg%fX(L~C*6WsdF+G`Dgok2KOhJ7-rOfYkUsY7U~;zmy^^w^lxrIv1|NzVLIG zg|NJsWxGf_U*Rnv{Ku1aei)6~Z&xpZ)9cs2sNpiK#RR5*b~TKLfV6(6gsvI>7pjZV zecGNM-^)A%F}LZxKnrZ29JEDTPoYm1V>xc#3uHC*DJTP0uY!>@Pk;BcL={6fv%?!zR#rOdDg)7!h?lp>vFL2+>($S{7@%u9Nx-T~&-8M`5<4WCQI2+hcwpeARWxXhjf-(OtmY-B zX{nuKzX)xkf2|uBdqa9x#T&*7DN{elujoCWezv&|QNMkwo>N4YmuC9tKZ!^ z04PAGt$)mO>8>ssY?*EQkECUu!~AS{tZ0MHlv?Kc7tn5!3|ME#Zie#~oh7r9+t2?r z16+{S$kRT9NEx6`^}Oa3sowBG-`+2oRuT1nur@uMvOPU}c+H}HG^UjHix@u1dr@d} zTw!%QWXFFkK>oQkK+?v=tXDDEMjMZJ=OgLQI(!ACKE;mF`m#zPV^iwliT-vh0#lvW zbYBf~Vgrec+XuMu&(p)(p;!HUK^4ANr zrs3fZ8D6W^%eehNY@O-4qS(@{uSG>s0TmGJ5NuGf!xljh6+4htQ1Ac5%B=b-ch&h@ zPu9v@I-8ggW4xm?SuVmtuR-O866@?!TdMRXIO?1~miW&SmiLOkvvvVUWzR+NK5V#O zwtUQLl;fv1hf;(^E;LT_Gg(Ilr|kyK|=vY7o5_Jk&2Ww;|0UdPjgsq3YlrxHs~N6ydX#oLQ_fu7hkE7u@%gRQAWkqAzPwA@^R53=Q3Nr?Mgj&n^khHnS(dp?EP9G3PClGCfn57yxh$syAJ){nX8-6i?_m*Va@0{)+0$1ncf;V$hyY7Z}rRqp_n^+VYf1wd65MH<6OIa5+~1) ze#nX!_)AzkOS;8pM`E}ZJM$mb;DoBKj`Is5)qVQ0ZFxU{=33W`oUYKewh38^Njr>EhA!X59` ztco|{Riw9)E04it9tDd6>^z0ozbQmrted++kvu0{z`;7rEE;{Be-5=nzoe;Uqf*Da zM{(r@VRVsyTu~7�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 literal 0 HcmV?d00001 diff --git a/benchmarking/benchmarking_bundles/datakrypto_tee_report.py b/benchmarking/benchmarking_bundles/datakrypto_tee_report.py new file mode 100644 index 000000000..30e7beb2b --- /dev/null +++ b/benchmarking/benchmarking_bundles/datakrypto_tee_report.py @@ -0,0 +1,979 @@ +""" +DataKrypto TEE Performance Analysis — PDF Report Generator +Run from repo root with virtual env active: + python benchmarking/benchmarking_bundles/datakrypto_tee_report.py +""" + +import io +import os +import struct +import sys +import warnings + +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import numpy as np +import pandas as pd + +warnings.filterwarnings('ignore') + +# ── reportlab ──────────────────────────────────────────────────────────────── +from reportlab.lib import colors +from reportlab.lib.enums import TA_CENTER, TA_JUSTIFY, TA_LEFT +from reportlab.lib.pagesizes import A4 +from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet +from reportlab.lib.units import cm, inch +from reportlab.platypus import ( + HRFlowable, Image, PageBreak, Paragraph, Spacer, Table, TableStyle, + SimpleDocTemplate, KeepTogether, +) + +# ── Paths ──────────────────────────────────────────────────────────────────── +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +DATA_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, '../data/datakrypto')) +OUT_PDF = os.path.join(SCRIPT_DIR, 'datakrypto_tee_performance_report.pdf') + +for p in [SCRIPT_DIR, os.path.join(SCRIPT_DIR, '../../'), + os.path.join(SCRIPT_DIR, '../../../')]: + if p not in sys.path: + sys.path.insert(0, p) + +# ── Palette ────────────────────────────────────────────────────────────────── +C_ENC = '#EF553B' +C_PLAIN = '#636EFA' +C_NET = '#FF7F0E' +C_ENCR = '#D62728' +C_DEC = '#2CA02C' +C_OTHER = '#9467BD' +C_NAVY = '#0d1b2a' +C_BLUE2 = '#1b4f72' +C_LIGHT = '#eaf4fb' +C_FIND = '#fef9e7' +C_WARN = '#fdedec' + +CONC_ORDER = [1, 2, 4, 8, 16, 32] + +# ═══════════════════════════════════════════════════════════════════════════ +# DATA LOADING +# ═══════════════════════════════════════════════════════════════════════════ + +DATASETS = { + 'enc_simple': { + 'consolidated': f'{DATA_ROOT}/speed_bench_test_encrypted_simple/consolidated_results/20260225-155057.028751.xlsx', + 'encrypted': True, 'run_type': 'Single Run (1x)', 'label': 'Encrypted', + }, + 'plain_simple': { + 'consolidated': f'{DATA_ROOT}/speed_bench_test_non_encrypted_simple/consolidated_results/20260227-204607.930274.xlsx', + 'encrypted': False, 'run_type': 'Single Run (1x)', 'label': 'Non-Encrypted', + }, + 'enc_multiple': { + 'consolidated': f'{DATA_ROOT}/speed_bench_test_encrypted_multiple/consolidated_results/20260225-150147.253373.xlsx', + 'encrypted': True, 'run_type': 'Multi Run (10x)', 'label': 'Encrypted', + }, + 'plain_multiple': { + 'consolidated': f'{DATA_ROOT}/speed_bench_test_non_encrypted_multiple/consolidated_results/20260227-205436.463636.xlsx', + 'encrypted': False, 'run_type': 'Multi Run (10x)', 'label': 'Non-Encrypted', + }, +} + +dfs = [] +for key, meta in DATASETS.items(): + df = pd.read_excel(meta['consolidated']) + df['dataset_key'] = key + df['encrypted'] = meta['encrypted'] + df['run_type'] = meta['run_type'] + df['label'] = meta['label'] + dfs.append(df) + +df_all = pd.concat(dfs, ignore_index=True) +df_all['total_requests'] = df_all['num_completed_requests'] + df_all['number_errors'] +df_all['error_rate_pct'] = ( + df_all['number_errors'] / df_all['total_requests'].replace(0, np.nan) +) * 100 + +DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests'] + +df_multi = df_all[df_all['run_type'] == 'Multi Run (10x)'] +df_enc_m = df_multi[df_multi['label'] == 'Encrypted'] +df_plain_m = df_multi[df_multi['label'] == 'Non-Encrypted'] + +# TEE overhead attribution (multi run, merged) +df_attr = df_enc_m.merge( + df_plain_m[DIMS + ['client_ttft_s_p50']].rename( + columns={'client_ttft_s_p50': 'client_ttft_plain'} + ), + on=DIMS, +) +df_attr['ttft_delta'] = df_attr['client_ttft_s_p50'] - df_attr['client_ttft_plain'] +df_attr['network_s'] = df_attr['server_network_latency_ms_mean'] / 1000 +df_attr['enc_s'] = df_attr['total_encryption_time_ms_mean'] / 1000 +df_attr['dec_s'] = df_attr['total_decryption_time_ms_mean'] / 1000 +df_attr['residual_s'] = (df_attr['ttft_delta'] - df_attr['network_s'] + - df_attr['enc_s'] - df_attr['dec_s']).clip(lower=0) + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART HELPERS +# ═══════════════════════════════════════════════════════════════════════════ + +PLT_STYLE = { + 'axes.spines.top': False, + 'axes.spines.right': False, + 'axes.grid': True, + 'grid.alpha': 0.35, + 'axes.labelsize': 9, + 'xtick.labelsize': 8, + 'ytick.labelsize': 8, + 'legend.fontsize': 8, + 'figure.facecolor': 'white', + 'axes.facecolor': 'white', +} + +def fig_to_image(fig, width_cm=16): + buf = io.BytesIO() + fig.savefig(buf, format='png', dpi=160, bbox_inches='tight') + plt.close(fig) + # Read PNG dimensions from header (bytes 16-23 after PNG signature + IHDR tag) + buf.seek(16) + px_w = struct.unpack('>I', buf.read(4))[0] + px_h = struct.unpack('>I', buf.read(4))[0] + buf.seek(0) + width_pts = width_cm * cm + height_pts = width_pts * px_h / px_w + img = Image(buf, width=width_pts, height=height_pts) + img.hAlign = 'CENTER' + return img + + +def line_chart(ax, x, y_enc, y_plain, ylabel, title, log_x=True): + """Shared enc vs plain line chart helper.""" + kw = dict(marker='o', markersize=4, linewidth=1.8) + ax.plot(x, y_enc, color=C_ENC, label='Encrypted', **kw) + ax.plot(x, y_plain, color=C_PLAIN, label='Non-Encrypted', **kw, linestyle='--') + if log_x: + ax.set_xscale('log', base=2) + ax.set_xticks(CONC_ORDER) + ax.set_xticklabels(CONC_ORDER) + ax.set_xlabel('Concurrency') + ax.set_ylabel(ylabel) + ax.set_title(title, fontsize=9, fontweight='bold') + ax.legend(framealpha=0.6) + + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART 1 — SERVER METRICS (assumption validation) +# ═══════════════════════════════════════════════════════════════════════════ + +def make_chart_server(): + with plt.rc_context(PLT_STYLE): + fig, axes = plt.subplots(2, 2, figsize=(11, 7)) + fig.suptitle('Server-Side Metrics — Encrypted vs Non-Encrypted', + fontsize=11, fontweight='bold', y=1.01) + + for col, out_tok in enumerate([100, 1024]): + enc_sub = df_enc_m[df_enc_m['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + plain_sub = df_plain_m[df_plain_m['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + x = enc_sub['num_concurrent_requests'].values + + line_chart( + axes[0, col], x, + enc_sub['server_ttft_s_p50'].values, + plain_sub['server_ttft_s_p50'].values, + 'Server TTFT p50 (s)', + f'Server TTFT — {out_tok} output tokens', + ) + line_chart( + axes[1, col], x, + enc_sub['server_output_token_per_s_p50'].values, + plain_sub['server_output_token_per_s_p50'].values, + 'Output Tok/s p50 (per request)', + f'Server Output Throughput — {out_tok} output tokens', + ) + + fig.tight_layout() + return fig_to_image(fig) + + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART 2 — TEE OVERHEAD BREAKDOWN +# ═══════════════════════════════════════════════════════════════════════════ + +def make_chart_tee_breakdown(): + with plt.rc_context(PLT_STYLE): + fig, axes = plt.subplots(1, 2, figsize=(11, 4.5)) + fig.suptitle('TEE Overhead Breakdown per Request (Encrypted, Multi Run)', + fontsize=11, fontweight='bold') + + for col, out_tok in enumerate([100, 1024]): + sub = df_attr[df_attr['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + x = np.arange(len(sub)) + xl = [str(c) for c in sub['num_concurrent_requests'].values] + ax = axes[col] + + b1 = ax.bar(x, sub['network_s'], color=C_NET, label='Network Hop', alpha=0.9) + b2 = ax.bar(x, sub['enc_s'], color=C_ENCR, label='Input Encryption', alpha=0.9, + bottom=sub['network_s']) + b3 = ax.bar(x, sub['dec_s'], color=C_DEC, label='Output Decryption',alpha=0.9, + bottom=sub['network_s'] + sub['enc_s']) + b4 = ax.bar(x, sub['residual_s'], color=C_OTHER,label='Residual', alpha=0.7, + bottom=sub['network_s'] + sub['enc_s'] + sub['dec_s']) + + # Annotate network % on each bar + for i, row in sub.iterrows(): + total = row['ttft_delta'] + if total > 0: + pct = row['network_s'] / row['client_ttft_s_p50'] * 100 + ax.text(list(sub.index).index(i), + row['network_s'] / 2, + f'{pct:.0f}%', ha='center', va='center', + fontsize=6.5, color='white', fontweight='bold') + + ax.set_xticks(x) + ax.set_xticklabels(xl) + ax.set_xlabel('Concurrency') + ax.set_ylabel('Overhead (s)') + ax.set_title(f'TEE Overhead — {out_tok} output tokens', fontsize=9, fontweight='bold') + if col == 0: + ax.legend(loc='upper left', fontsize=7.5, framealpha=0.7) + + fig.tight_layout() + return fig_to_image(fig) + + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART 3 — NETWORK LATENCY DETAIL +# ═══════════════════════════════════════════════════════════════════════════ + +def make_chart_network(): + df_enc_all = df_all[df_all['label'] == 'Encrypted'] + df_enc_s_all = df_enc_all[df_enc_all['run_type'] == 'Single Run (1x)'] + df_enc_m_all = df_enc_all[df_enc_all['run_type'] == 'Multi Run (10x)'] + + with plt.rc_context(PLT_STYLE): + fig, axes = plt.subplots(1, 2, figsize=(11, 4.5)) + fig.suptitle('TEE Network Latency vs Concurrency (Encrypted Model)', + fontsize=11, fontweight='bold') + + tok_colors = {100: '#1f77b4', 1024: '#ff7f0e'} + + for col, out_tok in enumerate([100, 1024]): + ax = axes[col] + for run_type, df_r, ls in [ + ('Single Run (1x)', df_enc_s_all, 'solid'), + ('Multi Run (10x)', df_enc_m_all, 'dashed'), + ]: + sub = df_r[df_r['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + ax.plot( + sub['num_concurrent_requests'], + sub['server_network_latency_ms_mean'], + color=tok_colors[out_tok], + linestyle=ls, + marker='o', markersize=4, linewidth=1.8, + label=run_type, + ) + + ax.set_xscale('log', base=2) + ax.set_xticks(CONC_ORDER) + ax.set_xticklabels(CONC_ORDER) + ax.set_xlabel('Concurrency (log scale)') + ax.set_ylabel('Network Latency — mean (ms)') + ax.set_title(f'Network Latency — {out_tok} output tokens', fontsize=9, fontweight='bold') + ax.legend(framealpha=0.6) + ax.axvline(x=8, color='red', linestyle=':', linewidth=1.2, alpha=0.6) + ax.text(8.5, ax.get_ylim()[1] * 0.92, 'TEE core\nlimit (8)', + color='red', fontsize=6.5, alpha=0.8) + + fig.tight_layout() + return fig_to_image(fig) + + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART 4 — CLIENT METRICS IMPACT +# ═══════════════════════════════════════════════════════════════════════════ + +def make_chart_client(): + with plt.rc_context(PLT_STYLE): + fig, axes = plt.subplots(2, 2, figsize=(11, 7)) + fig.suptitle('Client-Side Metrics — Encrypted vs Non-Encrypted (Multi Run)', + fontsize=11, fontweight='bold', y=1.01) + + for col, out_tok in enumerate([100, 1024]): + enc_sub = df_enc_m[df_enc_m['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + plain_sub = df_plain_m[df_plain_m['num_output_tokens'] == out_tok].sort_values('num_concurrent_requests') + x = enc_sub['num_concurrent_requests'].values + + line_chart( + axes[0, col], x, + enc_sub['client_ttft_s_p50'].values, + plain_sub['client_ttft_s_p50'].values, + 'Client TTFT p50 (s)', + f'Client TTFT — {out_tok} output tokens', + ) + # Shade the TEE overhead gap + axes[0, col].fill_between( + x, + plain_sub['client_ttft_s_p50'].values, + enc_sub['client_ttft_s_p50'].values, + alpha=0.12, color=C_ENC, label='TEE overhead gap', + ) + + line_chart( + axes[1, col], x, + enc_sub['num_completed_requests_per_min'].values, + plain_sub['num_completed_requests_per_min'].values, + 'Completed Requests / min', + f'System Throughput — {out_tok} output tokens', + ) + + fig.tight_layout() + return fig_to_image(fig) + + +# ═══════════════════════════════════════════════════════════════════════════ +# CHART 5 — ENCRYPTION / DECRYPTION TIMES +# ═══════════════════════════════════════════════════════════════════════════ + +def make_chart_crypto_times(): + df_enc_all = df_all[df_all['label'] == 'Encrypted'] + tok_colors = {100: '#1f77b4', 1024: '#ff7f0e'} + run_styles = {'Single Run (1x)': 'solid', 'Multi Run (10x)': 'dashed'} + + with plt.rc_context(PLT_STYLE): + fig, axes = plt.subplots(1, 2, figsize=(11, 4.5)) + fig.suptitle('TEE Encryption & Decryption Times vs Concurrency', + fontsize=11, fontweight='bold') + + shown = set() + for run_type, ls in run_styles.items(): + for out_tok, color in tok_colors.items(): + sub = df_enc_all[(df_enc_all['run_type'] == run_type) & + (df_enc_all['num_output_tokens'] == out_tok) + ].sort_values('num_concurrent_requests') + name = f'{out_tok} out | {run_type}' + show = name not in shown + + axes[0].plot(sub['num_concurrent_requests'], + sub['total_encryption_time_ms_mean'], + color=color, linestyle=ls, marker='o', + markersize=4, linewidth=1.8, + label=name if show else None) + axes[1].plot(sub['num_concurrent_requests'], + sub['total_decryption_time_ms_mean'], + color=color, linestyle=ls, marker='o', + markersize=4, linewidth=1.8, + label=name if show else None) + shown.add(name) + + for ax, title, ylabel in [ + (axes[0], 'Input Encryption Time', 'Time (ms)'), + (axes[1], 'Output Decryption Time', 'Time (ms)'), + ]: + ax.set_xscale('log', base=2) + ax.set_xticks(CONC_ORDER) + ax.set_xticklabels(CONC_ORDER) + ax.set_xlabel('Concurrency (log scale)') + ax.set_ylabel(ylabel) + ax.set_title(title, fontsize=9, fontweight='bold') + ax.legend(fontsize=7, framealpha=0.6) + + fig.tight_layout() + return fig_to_image(fig) + + +# ═══════════════════════════════════════════════════════════════════════════ +# REPORTLAB STYLES +# ═══════════════════════════════════════════════════════════════════════════ + +def build_styles(): + base = getSampleStyleSheet() + + styles = { + 'cover_title': ParagraphStyle( + 'cover_title', fontSize=26, fontName='Helvetica-Bold', + textColor=colors.white, alignment=TA_CENTER, spaceAfter=8, + ), + 'cover_sub': ParagraphStyle( + 'cover_sub', fontSize=13, fontName='Helvetica', + textColor=colors.HexColor('#aed6f1'), alignment=TA_CENTER, spaceAfter=4, + ), + 'cover_date': ParagraphStyle( + 'cover_date', fontSize=10, fontName='Helvetica', + textColor=colors.HexColor('#85c1e9'), alignment=TA_CENTER, + ), + 'h1': ParagraphStyle( + 'h1', fontSize=14, fontName='Helvetica-Bold', + textColor=colors.HexColor(C_NAVY), spaceBefore=14, spaceAfter=6, + borderPad=4, + ), + 'h2': ParagraphStyle( + 'h2', fontSize=11, fontName='Helvetica-Bold', + textColor=colors.HexColor(C_BLUE2), spaceBefore=10, spaceAfter=4, + ), + 'body': ParagraphStyle( + 'body', fontSize=9.5, fontName='Helvetica', + textColor=colors.HexColor('#2c3e50'), leading=14, + alignment=TA_JUSTIFY, spaceAfter=6, + ), + 'bullet': ParagraphStyle( + 'bullet', fontSize=9.5, fontName='Helvetica', + textColor=colors.HexColor('#2c3e50'), leading=14, + leftIndent=14, spaceAfter=3, + ), + 'finding_title': ParagraphStyle( + 'finding_title', fontSize=10, fontName='Helvetica-Bold', + textColor=colors.HexColor('#1a5276'), spaceAfter=3, + ), + 'finding_body': ParagraphStyle( + 'finding_body', fontSize=9, fontName='Helvetica', + textColor=colors.HexColor('#2c3e50'), leading=13, + ), + 'caption': ParagraphStyle( + 'caption', fontSize=8, fontName='Helvetica-Oblique', + textColor=colors.HexColor('#7f8c8d'), alignment=TA_CENTER, + spaceBefore=2, spaceAfter=10, + ), + 'table_hdr': ParagraphStyle( + 'table_hdr', fontSize=8.5, fontName='Helvetica-Bold', + textColor=colors.white, alignment=TA_CENTER, + ), + 'table_cell': ParagraphStyle( + 'table_cell', fontSize=8.5, fontName='Helvetica', + textColor=colors.HexColor('#2c3e50'), alignment=TA_CENTER, + ), + } + return styles + + +def finding_box(title, body_paragraphs, styles, bg=C_FIND, border=C_BLUE2): + """Highlighted finding box.""" + content = [Paragraph(f'🔍 {title}', styles['finding_title'])] + for p in body_paragraphs: + content.append(Paragraph(p, styles['finding_body'])) + tbl = Table([[content]], colWidths=[16.5 * cm]) + tbl.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor(bg)), + ('ROUNDEDCORNERS', [6]), + ('BOX', (0, 0), (-1, -1), 1.2, colors.HexColor(border)), + ('TOPPADDING', (0, 0), (-1, -1), 8), + ('BOTTOMPADDING',(0,0), (-1, -1), 8), + ('LEFTPADDING', (0, 0), (-1, -1), 10), + ('RIGHTPADDING',(0, 0), (-1, -1), 10), + ])) + return tbl + + +def warning_box(title, body, styles): + return finding_box(title, body, styles, bg=C_WARN, border='#e74c3c') + + +def section_rule(color=C_NAVY): + return HRFlowable(width='100%', thickness=1.5, + color=colors.HexColor(color), spaceAfter=6, spaceBefore=2) + + +# ═══════════════════════════════════════════════════════════════════════════ +# SUMMARY DATA TABLE +# ═══════════════════════════════════════════════════════════════════════════ + +def build_summary_table(styles): + """Side-by-side key metric table for multi run data.""" + + # Compute key numbers + rows_data = [] + for out_tok in [100, 1024]: + for conc in [1, 4, 8, 16, 32]: + enc_row = df_enc_m[(df_enc_m['num_output_tokens'] == out_tok) & + (df_enc_m['num_concurrent_requests'] == conc)] + plain_row = df_plain_m[(df_plain_m['num_output_tokens'] == out_tok) & + (df_plain_m['num_concurrent_requests'] == conc)] + if enc_row.empty or plain_row.empty: + continue + + e = enc_row.iloc[0] + p = plain_row.iloc[0] + + net_ms = e['server_network_latency_ms_mean'] + enc_ms = e['total_encryption_time_ms_mean'] + dec_ms = e['total_decryption_time_ms_mean'] + tee_total = net_ms + enc_ms + dec_ms + ttft_enc = e['client_ttft_s_p50'] + ttft_pln = p['client_ttft_s_p50'] + tee_pct = tee_total / 1000 / ttft_enc * 100 if ttft_enc else 0 + err_pct = e['error_rate_pct'] if pd.notna(e['error_rate_pct']) else 0 + + rows_data.append([ + f'{out_tok}', + f'{conc}', + f'{p["server_ttft_s_p50"]:.3f}', + f'{e["server_ttft_s_p50"]:.3f}', + f'{ttft_pln:.3f}', + f'{ttft_enc:.3f}', + f'{net_ms:.0f}', + f'{enc_ms:.1f}', + f'{dec_ms:.2f}', + f'{tee_pct:.0f}%', + f'{err_pct:.0f}%', + ]) + + headers = [ + 'Out\nTokens', 'Conc', + 'Server\nTTFT Plain', 'Server\nTTFT Enc', + 'Client\nTTFT Plain', 'Client\nTTFT Enc', + 'Network\n(ms)', 'Encrypt\n(ms)', 'Decrypt\n(ms)', + 'TEE %\nof TTFT', 'Error\nRate', + ] + + col_widths = [1.3*cm, 1.0*cm, 2.0*cm, 2.0*cm, 2.0*cm, 2.0*cm, + 1.7*cm, 1.6*cm, 1.6*cm, 1.6*cm, 1.5*cm] + + table_data = [[Paragraph(h, styles['table_hdr']) for h in headers]] + for rd in rows_data: + table_data.append([Paragraph(v, styles['table_cell']) for v in rd]) + + tbl = Table(table_data, colWidths=col_widths, repeatRows=1) + style = [ + ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor(C_NAVY)), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), + ('ALIGN', (0, 0), (-1, -1), 'CENTER'), + ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), + ('FONTSIZE', (0, 0), (-1, -1), 8), + ('ROWBACKGROUNDS',(0, 1), (-1, -1), [colors.white, colors.HexColor('#f2f3f4')]), + ('GRID', (0, 0), (-1, -1), 0.4, colors.HexColor('#bdc3c7')), + ('TOPPADDING', (0, 0), (-1, -1), 4), + ('BOTTOMPADDING',(0, 0), (-1, -1), 4), + ('ROWBACKGROUNDS',(0, 1), (-1, -1), [colors.white, colors.HexColor('#ebf5fb')]), + ] + # Highlight separator between 100 and 1024 token groups + n_100 = sum(1 for r in rows_data if r[0] == '100') + style.append(('LINEABOVE', (0, n_100 + 1), (-1, n_100 + 1), 1.5, colors.HexColor(C_NAVY))) + tbl.setStyle(TableStyle(style)) + return tbl + + +# ═══════════════════════════════════════════════════════════════════════════ +# PDF ASSEMBLY +# ═══════════════════════════════════════════════════════════════════════════ + +def build_pdf(): + from datetime import date as dt_date + + doc = SimpleDocTemplate( + OUT_PDF, + pagesize=A4, + leftMargin=1.8 * cm, + rightMargin=1.8 * cm, + topMargin=1.8 * cm, + bottomMargin=1.8 * cm, + ) + + S = build_styles() + story = [] + + # ── COVER ──────────────────────────────────────────────────────────── + # Dark header block + cover_bg = Table( + [[Paragraph('DataKrypto TEE', S['cover_title']),], + [Paragraph('Performance Impact Analysis', S['cover_title'])], + [Spacer(1, 0.3 * cm)], + [Paragraph('Encrypted vs Non-Encrypted Model Benchmarking Report', S['cover_sub'])], + [Spacer(1, 0.2 * cm)], + [Paragraph(f'Generated: {dt_date.today().strftime("%B %d, %Y")}', S['cover_date'])], + ], + colWidths=[16.5 * cm], + ) + cover_bg.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor(C_NAVY)), + ('TOPPADDING', (0, 0), (-1, -1), 18), + ('BOTTOMPADDING',(0, 0), (-1, -1), 18), + ('LEFTPADDING', (0, 0), (-1, -1), 20), + ('RIGHTPADDING', (0, 0), (-1, -1), 20), + ('ROUNDEDCORNERS', [8]), + ])) + story.append(cover_bg) + story.append(Spacer(1, 0.5 * cm)) + + story.append(section_rule()) + story.append(Paragraph('Executive Summary', S['h1'])) + story.append(Paragraph( + 'This report benchmarks SambaNova inference performance when accessed directly ' + '(plain model) versus through the DataKrypto Trusted Execution Environment (TEE) ' + '(encrypted model). The TEE adds a confidential computing layer that encrypts the ' + 'user prompt before sending it to the inference server and decrypts each streaming ' + 'output token chunk before returning it to the client, introducing an extra network ' + 'hop in the request path.', + S['body'], + )) + story.append(Paragraph( + 'Tests were run across concurrencies of 1, 2, 4, 8, 16, and 32 simultaneous ' + 'HTTP requests, with output token targets of 100 and 1,024, using a fixed ' + '2,000 input-token prompt. Two test modes were evaluated: a Single Run (one round ' + 'of N simultaneous requests) and a Multi Run (10 sequential rounds of N simultaneous ' + 'requests) for statistical stability.', + S['body'], + )) + + story.append(Paragraph('Key Findings', S['h2'])) + findings = [ + ('✅ Server assumption confirmed: With endpoints on equivalent configurations, ' + 'server TTFT and tok/s are nearly identical for both models at concurrency 1–4 ' + '(~0.091 s TTFT, ~585–620 tok/s). The TEE has no impact on inference speed ' + 'inside the SambaNova engine.'), + ('🔀 TEE de-batching effect — a hidden server benefit: Because the TEE processes ' + 'requests sequentially per core, concurrent requests arrive at the server staggered, ' + 'keeping the effective batch small. At concurrency 8–32, encrypted server TTFT stays ' + 'flat at ~0.163 s while non-encrypted TTFT doubles to ~0.311 s. At concurrency ≥ 16 ' + 'for short responses (100 tokens), this server-side advantage outweighs the TEE network ' + 'overhead — encrypted client TTFT actually becomes lower than non-encrypted.'), + ('🌐 Network hop is the dominant overhead at low concurrency: The extra ' + 'Client → TEE → Server roundtrip accounts for the bulk of the client-observable latency ' + 'increase at concurrency 1–8. At concurrency 1 with 100 output tokens, TEE network ' + 'latency is ~425 ms (Multi Run); for 1,024 output tokens it rises to ~1,600 ms.'), + ('🔐 Crypto overhead is negligible: Input encryption costs ~5–10 ms per ' + 'request (near-constant, independent of output length). Cumulative output decryption ' + 'costs ~0.1–4 ms total across all streaming chunks — both are negligible compared ' + 'to the network hop.'), + ('⚠️ TEE queue saturation at concurrency > 8: The TEE has 8 cores processing ' + 'encryption/decryption sequentially. Beyond 8 simultaneous requests, requests queue ' + 'at the TEE, causing network latency to grow non-linearly and error rates to climb ' + '(up to ~19% at concurrency 32 for 100 output tokens).'), + ('📉 System throughput gap at scale: Non-Encrypted throughput scales near-linearly ' + 'with concurrency (153 → 848 req/min for 100 output tokens). Encrypted throughput peaks ' + 'at concurrency 2 (~180 req/min) and drops to ~28 req/min at concurrency 32 — ' + 'a ~30× gap driven by TEE queueing and errors above concurrency 8.'), + ('🔁 Decryption grows linearly with output tokens because each streaming ' + 'chunk is decrypted individually by the TEE. Each chunk decryption costs on the ' + 'order of microseconds; the growth is real but the absolute values remain tiny.'), + ] + for f in findings: + story.append(Paragraph(f'• {f}', S['bullet'])) + + story.append(PageBreak()) + + # ── SECTION 1: ARCHITECTURE ───────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('1. Architecture & Test Setup', S['h1'])) + + story.append(Paragraph('Request Paths', S['h2'])) + arch_text = ( + 'Non-Encrypted: Client ──────────────────────────► SambaNova Inference Server
' + '                 (1 network hop — direct)

' + 'Encrypted:    Client ──► DataKrypto TEE ──► SambaNova Inference Server
' + '                         TEE encrypts input & decrypts each output chunk (streaming)
' + '                 (2 network hops total)
' + ) + arch_box = Table([[Paragraph(arch_text, S['body'])]], colWidths=[16.5*cm]) + arch_box.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#f8f9fa')), + ('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#bdc3c7')), + ('TOPPADDING', (0, 0), (-1, -1), 10), + ('BOTTOMPADDING', (0, 0), (-1, -1), 10), + ('LEFTPADDING', (0, 0), (-1, -1), 14), + ])) + story.append(arch_box) + story.append(Spacer(1, 0.3 * cm)) + + story.append(Paragraph('Models', S['h2'])) + model_tbl = Table( + [ + [Paragraph('Model', S['table_hdr']), + Paragraph('Description', S['table_hdr'])], + [Paragraph('Llama-xLAM-2-8b-fc-r', S['table_cell']), + Paragraph('Base model — direct plain inference', S['table_cell'])], + [Paragraph('Llama-xLAM-2-8b-fc-r-encrypted', S['table_cell']), + Paragraph('Same base architecture — routed through DataKrypto TEE', S['table_cell'])], + ], + colWidths=[7 * cm, 9.5 * cm], + ) + model_tbl.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor(C_NAVY)), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), + ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#bdc3c7')), + ('ROWBACKGROUNDS',(0, 1), (-1, -1), [colors.white, colors.HexColor('#ebf5fb')]), + ('TOPPADDING', (0, 0), (-1, -1), 5), + ('BOTTOMPADDING',(0, 0), (-1, -1), 5), + ('LEFTPADDING', (0, 0), (-1, -1), 8), + ])) + story.append(model_tbl) + story.append(Spacer(1, 0.3 * cm)) + + story.append(Paragraph('Test Matrix', S['h2'])) + story.append(Paragraph( + 'Input tokens: 2,000 (fixed)  |  ' + 'Output tokens: 100 and 1,024  |  ' + 'Concurrencies: 1, 2, 4, 8, 16, 32 simultaneous HTTP requests  |  ' + 'Single Run (1 round) + Multi Run (10 rounds)', + S['body'], + )) + story.append(Paragraph( + 'Each concurrency level sends N independent HTTP requests simultaneously — ' + 'not a single batched API call. The SambaNova server dynamically batches ' + 'simultaneous requests for inference. When the TEE is in the path, its sequential ' + 'per-core processing may stagger request arrival at the server, effectively ' + 'reducing the observed batch size.', + S['body'], + )) + + story.append(PageBreak()) + + # ── SECTION 2: SERVER METRICS ──────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('2. Server-Side Metrics — Assumption Validation', S['h1'])) + story.append(Paragraph( + 'With both SambaNova endpoints on equivalent configurations, server-side metrics directly ' + 'validate the core assumption: the TEE has no impact on inference speed inside the server. ' + 'At concurrency 1–4, both models show nearly identical server TTFT (~0.091 s) and output ' + 'tok/s (~585–620 tok/s). At higher concurrencies, the TEE de-batching effect becomes ' + 'visible: encrypted server TTFT stays flat at ~0.163 s while non-encrypted rises to ' + '~0.311 s as the server absorbs the full simultaneous batch.', + S['body'], + )) + story.append(make_chart_server()) + story.append(Paragraph( + 'Figure 1: Server TTFT p50 (top) and Server Output Tok/s p50 (bottom) for 100 and 1,024 ' + 'output tokens. Multi Run (10x). Solid = Encrypted, Dashed = Non-Encrypted.', + S['caption'], + )) + story.append(finding_box( + 'Finding: Server metrics confirm TEE adds zero inference overhead', + [ + 'At concurrency 1–4, server TTFT is ~0.091 s and server tok/s is ~585–620 tok/s ' + 'for both models — the values are virtually identical. This directly confirms that ' + 'the TEE does not slow down the SambaNova inference engine in any way.', + 'At concurrency 8–32, the TEE de-batching effect appears: encrypted server TTFT ' + 'stays at ~0.163 s while non-encrypted jumps to ~0.311 s. The TEE\'s sequential ' + 'per-core processing staggers request arrival, so the server sees a smaller effective ' + 'batch for encrypted requests. This lower server TTFT is a secondary benefit of the ' + 'TEE architecture — at high concurrency with short responses, it can more than ' + 'compensate for the TEE network overhead, making encrypted client TTFT lower than ' + 'non-encrypted at concurrency ≥ 16 (100 token responses).', + ], + S, + )) + + story.append(PageBreak()) + + # ── SECTION 3: TEE OVERHEAD ────────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('3. TEE Overhead Decomposition', S['h1'])) + story.append(Paragraph( + 'The TEE reports three measurable latency components per request. ' + 'Understanding their relative magnitudes is key to identifying where ' + 'improvement effort should be focused.', + S['body'], + )) + + # Component table + comp_tbl = Table( + [ + [Paragraph('Component', S['table_hdr']), + Paragraph('Source', S['table_hdr']), + Paragraph('Observed Range', S['table_hdr']), + Paragraph('Grows with…', S['table_hdr'])], + [Paragraph('Input Encryption', S['table_cell']), + Paragraph('TEE encrypts the 2,000-token prompt', S['table_cell']), + Paragraph('~5–10 ms', S['table_cell']), + Paragraph('Near-constant (independent of output)', S['table_cell'])], + [Paragraph('Output Decryption', S['table_cell']), + Paragraph('TEE decrypts each streaming chunk (per token batch)', S['table_cell']), + Paragraph('~0.1–4 ms total', S['table_cell']), + Paragraph('Output token count (linear, microseconds/chunk)', S['table_cell'])], + [Paragraph('Network Hop', S['table_cell']), + Paragraph('Extra Client→TEE→Server→TEE→Client roundtrip', S['table_cell']), + Paragraph('250 ms – 6,600 ms', S['table_cell']), + Paragraph('Concurrency (queue) + Output tokens (streaming RTTs)', S['table_cell'])], + ], + colWidths=[3.2*cm, 5.0*cm, 3.3*cm, 5.0*cm], + ) + comp_tbl.setStyle(TableStyle([ + ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor(C_NAVY)), + ('TEXTCOLOR', (0, 0), (-1, 0), colors.white), + ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#bdc3c7')), + ('ROWBACKGROUNDS',(0, 1), (-1, -1), [colors.white, colors.HexColor('#ebf5fb')]), + ('TOPPADDING', (0, 0), (-1, -1), 5), + ('BOTTOMPADDING',(0, 0), (-1, -1), 5), + ('LEFTPADDING', (0, 0), (-1, -1), 6), + ('RIGHTPADDING', (0, 0), (-1, -1), 6), + ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), + ('BACKGROUND', (0, 4), (-1, 4), colors.HexColor('#fef9e7')), # highlight network row + ])) + story.append(comp_tbl) + story.append(Spacer(1, 0.3 * cm)) + + story.append(make_chart_tee_breakdown()) + story.append(Paragraph( + 'Figure 2: TEE overhead per request broken down into Network Hop (orange), ' + 'Input Encryption (red), Output Decryption (green), and unexplained residual (purple). ' + 'Percentages inside bars = network hop as % of total encrypted client TTFT.', + S['caption'], + )) + + story.append(make_chart_crypto_times()) + story.append(Paragraph( + 'Figure 3: Encryption time (left) and decryption time (right) vs concurrency. ' + 'Solid lines = Single Run, Dashed = Multi Run. ' + 'Blue = 100 output tokens, Orange = 1,024 output tokens.', + S['caption'], + )) + + story.append(finding_box( + 'Finding: Network hop dominates — crypto overhead is negligible', + [ + 'The network hop accounts for 85–97% of the total TEE overhead in every scenario. ' + 'Input encryption is approximately constant at ~5–10 ms and decreases slightly at ' + 'higher concurrencies (likely TEE CPU sharing effects). Output decryption grows ' + 'linearly with output tokens (~0.1 ms for 100 tokens, ~3–4 ms for 1,024 tokens) ' + 'because each streaming chunk is decrypted individually — each chunk costs on the ' + 'order of microseconds.', + 'Implication: Optimising the encryption/decryption algorithm would have minimal ' + 'impact. Reducing the network roundtrip time (physical proximity of TEE to ' + 'client and to the inference server) is the highest-leverage improvement.', + ], + S, + )) + + story.append(PageBreak()) + + # ── SECTION 4: NETWORK LATENCY ─────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('4. Network Latency Growth Pattern', S['h1'])) + story.append(Paragraph( + 'The TEE network latency grows along two dimensions: concurrency (TEE queue depth) ' + 'and output token count (more streaming chunks = more decryption RTTs).', + S['body'], + )) + story.append(make_chart_network()) + story.append(Paragraph( + 'Figure 4: TEE network latency vs concurrency for 100 output tokens (left) ' + 'and 1,024 output tokens (right). Solid = Single Run, Dashed = Multi Run. ' + 'Red vertical line marks the TEE 8-core limit.', + S['caption'], + )) + story.append(finding_box( + 'Finding: Two distinct growth regimes', + [ + 'Below TEE capacity (concurrency ≤ 8): Network latency grows moderately ' + 'because requests can be processed in parallel across available cores. ' + 'At concurrency 1 with 100 output tokens the mean network latency is ~425 ms ' + '(Multi Run); at concurrency 8 it rises to ~638 ms.', + 'Above TEE capacity (concurrency > 8): Requests queue at the TEE, ' + 'causing network latency to grow faster. At concurrency 32 with 100 output ' + 'tokens it reaches ~803 ms; for 1,024 output tokens it can exceed 3,100 ms. ' + 'This is where error rates also begin to climb.', + 'Output tokens scale the baseline: Longer responses require more ' + 'streaming decrypt RTTs. At concurrency 1, the jump from 100 to 1,024 output ' + 'tokens increases network latency from ~425 ms to ~1,608 ms (~3.8×).', + ], + S, + )) + + story.append(PageBreak()) + + # ── SECTION 5: CLIENT IMPACT ───────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('5. Client-Side Impact — User-Facing Latency', S['h1'])) + story.append(Paragraph( + 'Client TTFT and system throughput capture the full end-user experience ' + 'including all TEE overhead. The shaded area in the TTFT chart represents ' + 'the TEE overhead gap.', + S['body'], + )) + story.append(make_chart_client()) + story.append(Paragraph( + 'Figure 5: Client TTFT p50 (top) and completed requests per minute (bottom) ' + 'for 100 and 1,024 output tokens. Multi Run (10x). ' + 'At concurrency ≥ 16 (100 tokens), encrypted TTFT drops below non-encrypted ' + 'due to the TEE de-batching benefit on server prefill time.', + S['caption'], + )) + story.append(warning_box( + 'Warning: System throughput gap widens at high concurrency (Encrypted)', + [ + 'Non-Encrypted throughput scales near-linearly with concurrency, ' + 'reaching ~848 req/min at concurrency 32 (100 output tokens). ' + 'Encrypted throughput peaks at concurrency 2 (~180 req/min) and ' + 'falls to ~28 req/min at concurrency 32 — a ~30× gap. This collapse ' + 'is driven by the TEE queue building up (>8 cores) and requests experiencing ' + 'progressively longer network waits. At concurrency >8, error rates reach ' + '11–19%, further reducing effective throughput. ' + 'Note: despite lower per-request TTFT at high concurrency for 100-token ' + 'responses, the overall system throughput (req/min) remains far lower for ' + 'the encrypted path due to TEE queueing and errors.', + ], + S, + )) + + story.append(PageBreak()) + + # ── SECTION 6: SUMMARY TABLE ───────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('6. Summary Data Table (Multi Run)', S['h1'])) + story.append(Paragraph( + 'All latency values in seconds unless noted. ' + 'TEE % = (network + encryption + decryption) / encrypted client TTFT × 100.', + S['body'], + )) + story.append(build_summary_table(S)) + story.append(Spacer(1, 0.4 * cm)) + + story.append(PageBreak()) + + # ── SECTION 7: CONCLUSIONS ─────────────────────────────────────────── + story.append(section_rule()) + story.append(Paragraph('7. Conclusions', S['h1'])) + + conclusions = [ + ('TEE adds zero server inference overhead — confirmed. With equivalent endpoint ' + 'configurations, server TTFT and tok/s are nearly identical at concurrency 1–4 ' + '(~0.091 s and ~585–620 tok/s respectively). The TEE de-batching effect is also ' + 'confirmed: at concurrency 8–32, encrypted server TTFT stays flat at ~0.163 s while ' + 'non-encrypted rises to ~0.311 s. At concurrency ≥ 16 with short responses, this ' + 'server-side benefit can outweigh the TEE network overhead entirely.'), + ('The overhead is entirely network-driven. The extra network hop through ' + 'the TEE accounts for 85–97% of the additional client-visible latency. ' + 'Encryption (~5–10 ms) and decryption (~0.1–4 ms cumulative) are negligible.'), + ('Network latency is predictable at low concurrency. Below TEE capacity ' + '(concurrency ≤ 8), the added latency is roughly constant per round-trip and ' + 'scales linearly with output token count — consistent with the TEE team\'s claims.'), + ('TEE queue saturation is the critical scalability limit. At concurrency > 8, ' + 'the 8-core TEE begins queuing requests, causing latency to grow non-linearly ' + 'and error rates to increase. Production deployments should stay at or below ' + 'the TEE core count for reliable performance.'), + ('Per-user latency overhead at concurrency 1: Client TTFT increases by ' + '~0.19 s (100 output tokens) to ~0.17 s (1,024 output tokens) in Multi Run — ' + 'relatively modest for a confidential computing solution.'), + ] + for c in conclusions: + story.append(Paragraph(f'• {c}', S['bullet'])) + story.append(Spacer(1, 0.15 * cm)) + + story.append(Spacer(1, 0.4 * cm)) + story.append(Paragraph('Recommendations', S['h2'])) + recs = [ + 'Reduce TEE network latency: Co-locate the TEE as close as possible to both ' + 'the client and the SambaNova inference server to minimise round-trip times.', + 'Respect TEE core limit: Keep concurrent request load at or below 8 to avoid ' + 'queue saturation. Above this point latency grows non-linearly and errors appear.', + 'No need to optimise crypto: Encryption and decryption are already fast enough ' + 'that further optimisation would have negligible user-visible impact.', + 'Scale horizontally: For higher throughput with the TEE, scale the number of ' + 'TEE instances rather than increasing concurrency per instance beyond 8.', + ] + for r in recs: + story.append(Paragraph(f'• {r}', S['bullet'])) + story.append(Spacer(1, 0.1 * cm)) + + story.append(Spacer(1, 0.5 * cm)) + story.append(section_rule(color='#bdc3c7')) + story.append(Paragraph( + f'DataKrypto × SambaNova — Confidential Benchmarking Report — {dt_date.today().strftime("%B %Y")}', + ParagraphStyle('footer', fontSize=7.5, fontName='Helvetica', + textColor=colors.HexColor('#95a5a6'), alignment=TA_CENTER), + )) + + doc.build(story) + print(f'✅ Report saved to: {OUT_PDF}') + + +if __name__ == '__main__': + build_pdf() diff --git a/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis.ipynb b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis.ipynb new file mode 100644 index 000000000..1187ddc4e --- /dev/null +++ b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis.ipynb @@ -0,0 +1,27218 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "cell-setup", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setup complete\n" + ] + } + ], + "source": [ + "import os\n", + "import sys\n", + "import warnings\n", + "import numpy as np\n", + "import pandas as pd\n", + "import plotly.express as px\n", + "import plotly.graph_objects as go\n", + "from plotly.subplots import make_subplots\n", + "\n", + "warnings.filterwarnings('ignore')\n", + "pd.set_option('display.float_format', '{:.4f}'.format)\n", + "pd.set_option('display.max_columns', 50)\n", + "\n", + "for rel_path in ['../', '../../', '../../../']:\n", + " abs_path = os.path.abspath(rel_path)\n", + " if abs_path not in sys.path:\n", + " sys.path.insert(0, abs_path)\n", + "\n", + "from benchmarking.utils import read_perf_eval_json_files\n", + "\n", + "COLOR_MAP = {'Encrypted': '#EF553B', 'Non-Encrypted': '#636EFA'}\n", + "SYMBOL_MAP = {'Encrypted': 'circle', 'Non-Encrypted': 'square'}\n", + "CONC_ORDER = [1, 2, 4, 8, 16, 32]\n", + "CONC_STR = [str(c) for c in CONC_ORDER]\n", + "\n", + "print('Setup complete')" + ] + }, + { + "cell_type": "markdown", + "id": "cell-title", + "metadata": {}, + "source": [ + "# DataKrypto TEE Performance Analysis\n", + "## Encrypted vs Non-Encrypted Model — Benchmarking Report\n", + "\n", + "---\n", + "\n", + "### Architecture\n", + "\n", + "```\n", + "Non-Encrypted:\n", + " Client ──────────────────────────► SambaNova Inference Server\n", + " (1 network hop)\n", + "\n", + "Encrypted:\n", + " Client ──► DataKrypto TEE ───────► SambaNova Inference Server\n", + " │ encrypts input returns encrypted chunks\n", + " │ decrypts each output ◄─────────────────────────┘\n", + " │ chunk (streaming)\n", + " └──► Client\n", + " (2 network hops total)\n", + "```\n", + "\n", + "### Models\n", + "| Model | Description |\n", + "|-------|-------------|\n", + "| `Llama-xLAM-2-8b-fc-r` | Base model (plain inference) |\n", + "| `Llama-xLAM-2-8b-fc-r-encrypted` | Runs through DataKrypto TEE |\n", + "\n", + "> Note: The two models are served by **separate SambaNova endpoints** which may have\n", + "> different hardware allocations or decode configurations. Any baseline performance\n", + "> difference between them is an endpoint-level characteristic — not caused by the TEE.\n", + "\n", + "### Test Matrix\n", + "- **Input tokens**: 2,000 (fixed)\n", + "- **Output tokens**: 100 and 1,024\n", + "- **Concurrencies**: 1, 2, 4, 8, 16, 32\n", + "- Each concurrency level = **N separate HTTP requests sent simultaneously** (not a single batch API call — N independent requests hitting the server at the same time, which the server can dynamically batch together for inference)\n", + "- **Single Run (1x)**: One round of N simultaneous requests — clean first-hit baseline at each concurrency level\n", + "- **Multi Run (10x)**: 10 sequential rounds of the same N simultaneous requests — same per-round server load as Single Run, but repeated 10 times. Provides statistical robustness and tests sustained server/TEE behavior over time\n", + "\n", + "> Key difference: Single and Multi Run have the **same per-round concurrency load**.\n", + "> Multi Run adds statistical reliability (more samples) and reveals sustained-load behavior —\n", + "> it does not increase the number of simultaneous requests per round.\n", + "\n", + "### TEE Overhead Sources\n", + "1. **Input Encryption** — encrypts the prompt (~4–10 ms, near-constant per request)\n", + "2. **Output Decryption** — decrypts each streaming token chunk (grows with output tokens)\n", + "3. **Network Hop** — extra Client → TEE → Server roundtrip (dominant overhead)\n", + "\n", + "> **TEE capacity constraint**: The TEE has **8 cores** and processes encryption/decryption\n", + "> sequentially per core. At concurrency > 8, the TEE queue fills up causing requests to wait,\n", + "> which means concurrent requests may arrive at the inference server **staggered** rather than\n", + "> simultaneously — reducing the effective batch size the server sees.\n", + "\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-load", + "metadata": {}, + "outputs": [], + "source": "DATA_ROOT = os.path.abspath('../../data/datakrypto')\n\nDATASETS = {\n 'enc_simple': {\n 'consolidated': f'{DATA_ROOT}/speed_bench_test_encrypted_simple/consolidated_results/20260225-155057.028751.xlsx',\n 'run_dir': f'{DATA_ROOT}/speed_bench_test_encrypted_simple/20260225-155057.028751',\n 'encrypted': True, \n 'run_type': 'Single Run (1x)', \n 'label': 'Encrypted',\n },\n 'plain_simple': {\n 'consolidated': f'{DATA_ROOT}/speed_bench_test_non_encrypted_simple/consolidated_results/20260227-204607.930274.xlsx',\n 'run_dir': f'{DATA_ROOT}/speed_bench_test_non_encrypted_simple/20260227-204607.930274',\n 'encrypted': False, \n 'run_type': 'Single Run (1x)', \n 'label': 'Non-Encrypted',\n },\n 'enc_multiple': {\n 'consolidated': f'{DATA_ROOT}/speed_bench_test_encrypted_multiple/consolidated_results/20260225-150147.253373.xlsx',\n 'run_dir': f'{DATA_ROOT}/speed_bench_test_encrypted_multiple/20260225-150147.253373',\n 'encrypted': True, \n 'run_type': 'Multi Run (10x)', \n 'label': 'Encrypted',\n },\n 'plain_multiple': {\n 'consolidated': f'{DATA_ROOT}/speed_bench_test_non_encrypted_multiple/consolidated_results/20260227-205436.463636.xlsx',\n 'run_dir': f'{DATA_ROOT}/speed_bench_test_non_encrypted_multiple/20260227-205436.463636',\n 'encrypted': False, \n 'run_type': 'Multi Run (10x)', \n 'label': 'Non-Encrypted',\n },\n}\n\ndfs = []\nfor key, meta in DATASETS.items():\n df = pd.read_excel(meta['consolidated'])\n df['dataset_key'] = key\n df['encrypted'] = meta['encrypted']\n df['run_type'] = meta['run_type']\n df['label'] = meta['label']\n dfs.append(df)\n\ndf_all = pd.concat(dfs, ignore_index=True)\n\n# Derived columns\ndf_all['out_tokens_label'] = df_all['num_output_tokens'].astype(str) + ' output tokens'\ndf_all['total_requests'] = df_all['num_completed_requests'] + df_all['number_errors']\ndf_all['error_rate_pct'] = (df_all['number_errors'] / df_all['total_requests'].replace(0, np.nan)) * 100\ndf_all['completion_rate_pct'] = 100 - df_all['error_rate_pct']\n\n# Ordered categorical for consistent facet ordering\ndf_all['run_type'] = pd.Categorical(\n df_all['run_type'],\n categories=['Single Run (1x)', 'Multi Run (10x)'],\n ordered=True\n)\n\nprint(f'Loaded {len(df_all)} rows across {df_all[\"dataset_key\"].nunique()} datasets')\ndf_all.groupby(['label', 'run_type'])[['num_concurrent_requests']].count().rename(columns={'num_concurrent_requests': 'scenarios'})" + }, + { + "cell_type": "markdown", + "id": "cell-overview-hdr", + "metadata": {}, + "source": [ + "## 1. Dataset Overview" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "cell-overview", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 ModelRun TypeOutput TokensConcurrencyCompletedErrorsError Rate (%)
0EncryptedSingle Run (1x)1001100.0%
1EncryptedSingle Run (1x)1002200.0%
2EncryptedSingle Run (1x)1004400.0%
3EncryptedSingle Run (1x)1008800.0%
4EncryptedSingle Run (1x)100161600.0%
5EncryptedSingle Run (1x)100323200.0%
6EncryptedSingle Run (1x)10241100.0%
7EncryptedSingle Run (1x)10242200.0%
8EncryptedSingle Run (1x)10244400.0%
9EncryptedSingle Run (1x)10248800.0%
10EncryptedSingle Run (1x)1024161600.0%
11EncryptedSingle Run (1x)1024323200.0%
12Non-EncryptedSingle Run (1x)1001100.0%
13Non-EncryptedSingle Run (1x)1002200.0%
14Non-EncryptedSingle Run (1x)1004400.0%
15Non-EncryptedSingle Run (1x)1008800.0%
16Non-EncryptedSingle Run (1x)100161600.0%
17Non-EncryptedSingle Run (1x)100323200.0%
18Non-EncryptedSingle Run (1x)10241100.0%
19Non-EncryptedSingle Run (1x)10242200.0%
20Non-EncryptedSingle Run (1x)10244400.0%
21Non-EncryptedSingle Run (1x)10248800.0%
22Non-EncryptedSingle Run (1x)1024161600.0%
23Non-EncryptedSingle Run (1x)1024323200.0%
24EncryptedMulti Run (10x)10011000.0%
25EncryptedMulti Run (10x)10022000.0%
26EncryptedMulti Run (10x)10044000.0%
27EncryptedMulti Run (10x)10088000.0%
28EncryptedMulti Run (10x)100161421811.2%
29EncryptedMulti Run (10x)100322586219.4%
30EncryptedMulti Run (10x)102411000.0%
31EncryptedMulti Run (10x)102422000.0%
32EncryptedMulti Run (10x)102444000.0%
33EncryptedMulti Run (10x)102487911.2%
34EncryptedMulti Run (10x)102416146148.8%
35EncryptedMulti Run (10x)1024322645617.5%
36Non-EncryptedMulti Run (10x)10011000.0%
37Non-EncryptedMulti Run (10x)10022000.0%
38Non-EncryptedMulti Run (10x)10044000.0%
39Non-EncryptedMulti Run (10x)10088000.0%
40Non-EncryptedMulti Run (10x)1001616000.0%
41Non-EncryptedMulti Run (10x)1003232000.0%
42Non-EncryptedMulti Run (10x)102411000.0%
43Non-EncryptedMulti Run (10x)102422000.0%
44Non-EncryptedMulti Run (10x)102444000.0%
45Non-EncryptedMulti Run (10x)102488000.0%
46Non-EncryptedMulti Run (10x)10241616000.0%
47Non-EncryptedMulti Run (10x)10243232000.0%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cols = ['label', \n", + " 'run_type', \n", + " 'num_output_tokens', \n", + " 'num_concurrent_requests',\n", + " 'num_completed_requests', \n", + " 'number_errors', \n", + " 'error_rate_pct'\n", + " ]\n", + "overview = df_all[cols].copy()\n", + "overview.columns = ['Model', \n", + " 'Run Type', \n", + " 'Output Tokens', \n", + " 'Concurrency',\n", + " 'Completed', \n", + " 'Errors', \n", + " 'Error Rate (%)'\n", + " ]\n", + "overview['Error Rate (%)'] = overview['Error Rate (%)'].fillna(0).round(1)\n", + "overview = overview.sort_values(['Run Type', 'Model', 'Output Tokens', 'Concurrency'])\n", + "\n", + "def _highlight_errors(row):\n", + " if row['Errors'] > 0:\n", + " return ['background-color: #ffdddd'] * len(row)\n", + " return [''] * len(row)\n", + "\n", + "overview.style.apply(_highlight_errors, axis=1).format({'Error Rate (%)': '{:.1f}%'})" + ] + }, + { + "cell_type": "markdown", + "id": "cell-errors-hdr", + "metadata": {}, + "source": [ + "## 2. Error & Completion Rate Analysis\n", + "\n", + "The TEE has **8 cores** processing encryption/decryption sequentially.\n", + "At concurrency > 8, the TEE queue fills up and requests may time out or be rejected,\n", + "producing errors on the encrypted model only. The plain model should show zero errors." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "cell-errors-chart", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAmQAAAAAAAYDNA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9D8AAAAAAIAhQAAAAAAAgDFA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "group", + "height": 600, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Request Error Rate by Concurrency
Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). Non-Encrypted should be 0% throughout." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.48 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Error Rate (%)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Error Rate (%)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.bar(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='error_rate_pct',\n", + " color='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='group',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'error_rate_pct': 'Error Rate (%)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Request Error Rate by Concurrency
'\n", + " 'Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). '\n", + " 'Non-Encrypted should be 0% throughout.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=600, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "cell-reqmin-chart", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "d76fGi+dSUDFILByaE1bQBDpt68DYHBAFNBE2PB7ekBwzojS3haBQNuK/WV3nINA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "CmgibHgKZUBrmnecopNLQFInoImwaUpAMlUwKqmbW0Bhw9MrZW9iQOJYF7fR+GVA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "RpT2Bl94W0DDZKpgVHpmQMKGp1fKoj9A3bWEfNArQkA4Z0Rpb4A9QHNoke18bzxA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "ysNCrWkOQUCC4seYu3ZGQHgLJCh+fEdA2c73U+MVPkBWfa62Yr88QHBfB84ZgT5A", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "cF8HzhlVWEBbsb/snnBlQLHh6ZWyO3FAGw3gLZD4fEDVCWgibNGBQN/gC5MpoYJA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "MQisHFpUQEA9CtejcA1MQG/whclU+VNAokW28/2AYUC5jQbwFkRnQApoImx4qG1A", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "fT81XrohY0CIhVrTvEdnQJZDi2znW3ZAeekmMYgugUCDUUmdgDqKQGHD0ytlgopA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "jNtoAG9JQEDrc7UV++NCQE+vlGWIo1RAzF1LyAcVYkBpb/CFybNyQKhXyjLEVnNA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "System Throughput: Completed Requests per Minute
ndicator of system capacity. Encrypted model throughput is severely limited by TEE queueing at higher concurrencies." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.48 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Completed Requests / min" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Completed Requests / min" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Completed requests per minute — real system throughput capacity\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='num_completed_requests_per_min',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'num_completed_requests_per_min': 'Completed Requests / min',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'System Throughput: Completed Requests per Minute
'\n", + " 'ndicator of system capacity. '\n", + " 'Encrypted model throughput is severely limited by TEE queueing at higher concurrencies.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "id": "cell-server-hdr", + "metadata": {}, + "source": "## 3. Server-Side Metrics — Assumption Validation ✅\n\nWith both endpoints on equivalent configurations, server-side metrics now confirm the core assumption:\n**the TEE does not affect inference speed inside the SambaNova engine.**\n\n**Server tok/s — endpoints are now matched:**\n- Both endpoints baseline at ~585–620 tok/s (ratio 1.02–1.06× at concurrency 1–2 and 8+)\n- A small anomaly remains at concurrency 4 (ratio ~1.33–1.46×) which may be a transient batching artifact\n- The previous 1.87× gap was an endpoint configuration issue, now resolved\n\n**Server TTFT — two distinct regimes clearly visible:**\n- **Concurrency 1–4**: Both models show nearly identical server TTFT (~0.091 s and ~0.161 s respectively)\n — direct confirmation that the TEE has no impact on server prefill latency\n- **Concurrency 8–32**: Encrypted stays flat at ~0.163 s; non-encrypted jumps to ~0.311 s.\n This divergence is the **TEE de-batching effect** in action: because the TEE processes\n requests sequentially per core, they arrive at the server staggered rather than simultaneously,\n keeping the effective server batch smaller and prefill latency lower for the encrypted path.\n\n**Interesting consequence at high concurrency:** The encrypted model's server-side advantage from\nde-batching (lower TTFT) can exceed the TEE network overhead, making encrypted client TTFT\nactually lower than non-encrypted at concurrency ≥ 16 for 100-token responses (see Section 5)." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-ttft", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='out_tokens_label',\n facet_row='run_type',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_ttft_s_p50': 'Server TTFT p50 (s)',\n 'label': 'Model',\n 'out_tokens_label': 'Output Tokens',\n 'run_type': 'Run Type',\n },\n title=(\n 'Server Time to First Token — p50
'\n 'Concurrency 1–4: nearly identical for both models ✅ — confirms TEE has no server-side impact. '\n 'Concurrency 8–32: encrypted stays flat (~0.163 s), non-encrypted rises to ~0.311 s. '\n 'This split is the TEE de-batching effect: staggered arrival keeps the effective server batch '\n 'smaller for the encrypted path, reducing prefill queue time.'\n ),\n)\nfig.update_layout(height=700, width=1100, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-toks", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_output_token_per_s_p50',\n color='label',\n symbol='label',\n facet_col='out_tokens_label',\n facet_row='run_type',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_output_token_per_s_p50': 'Server Output Tok/s p50 (per request)',\n 'label': 'Model',\n 'out_tokens_label': 'Output Tokens',\n 'run_type': 'Run Type',\n },\n title=(\n 'Server Output Throughput per Request — p50
'\n 'Both endpoints now matched (~585–620 tok/s). Small gap at conc=4 may be a batching artifact. '\n 'Encrypted stays flat across all concurrencies (TEE de-batching keeps effective server batch small). '\n 'Non-Encrypted baseline is slightly higher but both degrade similarly at large batches.'\n ),\n)\nfig.update_layout(height=700, width=1100, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "cell-server-e2e", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "mSoYldQJuD9fKcsQx7rQP5Cg+DHmrtE/JQaBlUOL3D+BBMWPMXfZP1JJnYAmwt4/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "8WPMXUvItz87AU2EDU/tPyL99nXgnP4/gnNGlPYG/D9b07zjFB3+PwWjkjoBTfw/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "tTf4wmSq0D+C4seYu5bQP+eMKO0NvtA/ObTIdr6f0j8nwoanV8rSP0GC4seYu9I/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "RUdy+Q/p/D9UdCSX/5D8PyDSb18Hzvg/ufyH9NvX9z8Xt9EA3gL8P95xio7k8vk/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "u7iNBvAW0D9d3EYDeAvQP6CJsOHpldI/ObTIdr6f3j8hH/RsVn3eP4/C9Shcj94/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "N4lBYOXQ+z8bL90kBgEAQGsr9pfdk/A/MZkqGJXU9j8noImw4en2PyqpE9BE2PY/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "5j+k374O0D9uowG8BRLQPwCRfvs6cNI/vHSTGARW3j8Jih9j7lreP+/Jw0Ktad4/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "okW28/3U+z9m9+Rhodb7P/OOU3Qkl/A/QmDl0CLb9j/oaiv2l932PyqpE9BE2PY/", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server End-to-End Latency — p50" + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.48 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Server E2E Latency p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Server E2E Latency p50 (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='server_end_to_end_latency_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_end_to_end_latency_s_p50': 'Server E2E Latency p50 (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title='Server End-to-End Latency — p50',\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "cell-server-delta", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 MetricRun TypeOutput TokensConcurrencyNon-EncryptedEncryptedDelta% Change
58Server E2E p50 (s)Multi Run (10x)10010.25090.2604+0.0095+3.8%
59Server E2E p50 (s)Multi Run (10x)10020.25110.2592+0.0081+3.2%
60Server E2E p50 (s)Multi Run (10x)10040.28810.2616-0.0265-9.2%
61Server E2E p50 (s)Multi Run (10x)10080.47400.2910-0.1830-38.6%
62Server E2E p50 (s)Multi Run (10x)100160.47430.2936-0.1807-38.1%
63Server E2E p50 (s)Multi Run (10x)100320.47520.2927-0.1825-38.4%
64Server E2E p50 (s)Multi Run (10x)102411.73951.8069+0.0674+3.9%
65Server E2E p50 (s)Multi Run (10x)102421.73991.7854+0.0455+2.6%
66Server E2E p50 (s)Multi Run (10x)102441.03691.5503+0.5134+49.5%
67Server E2E p50 (s)Multi Run (10x)102481.42851.4902+0.0617+4.3%
68Server E2E p50 (s)Multi Run (10x)1024161.42911.7507+0.3216+22.5%
69Server E2E p50 (s)Multi Run (10x)1024321.42781.6218+0.1940+13.6%
46Server E2E p50 (s)Single Run (1x)10010.25140.0939-0.1575-62.6%
47Server E2E p50 (s)Single Run (1x)10020.25070.2614+0.0107+4.3%
48Server E2E p50 (s)Single Run (1x)10040.29040.2763-0.0141-4.9%
49Server E2E p50 (s)Single Run (1x)10080.47850.4460-0.0325-6.8%
50Server E2E p50 (s)Single Run (1x)100160.47640.3979-0.0785-16.5%
51Server E2E p50 (s)Single Run (1x)100320.47750.4806+0.0031+0.6%
52Server E2E p50 (s)Single Run (1x)102411.73850.0929-1.6456-94.7%
53Server E2E p50 (s)Single Run (1x)102422.00050.9159-1.0846-54.2%
54Server E2E p50 (s)Single Run (1x)102441.03611.9133+0.8772+84.7%
55Server E2E p50 (s)Single Run (1x)102481.42691.7517+0.3248+22.8%
56Server E2E p50 (s)Single Run (1x)1024161.43211.8821+0.4500+31.4%
57Server E2E p50 (s)Single Run (1x)1024321.42781.7688+0.3410+23.9%
12Server TTFT p50 (s)Multi Run (10x)10010.09110.0910-0.0001-0.1%
13Server TTFT p50 (s)Multi Run (10x)10020.09120.0902-0.0010-1.1%
14Server TTFT p50 (s)Multi Run (10x)10040.16080.1615+0.0007+0.4%
15Server TTFT p50 (s)Multi Run (10x)10080.31080.1619-0.1489-47.9%
16Server TTFT p50 (s)Multi Run (10x)100160.31100.1646-0.1464-47.1%
17Server TTFT p50 (s)Multi Run (10x)100320.31170.1636-0.1481-47.5%
18Server TTFT p50 (s)Multi Run (10x)102410.09180.0913-0.0005-0.5%
19Server TTFT p50 (s)Multi Run (10x)102420.09210.0917-0.0004-0.4%
20Server TTFT p50 (s)Multi Run (10x)102440.16060.1632+0.0026+1.6%
21Server TTFT p50 (s)Multi Run (10x)102480.31160.1605-0.1511-48.5%
22Server TTFT p50 (s)Multi Run (10x)1024160.31150.3108-0.0007-0.2%
23Server TTFT p50 (s)Multi Run (10x)1024320.31060.1666-0.1440-46.4%
0Server TTFT p50 (s)Single Run (1x)10010.09130.0928+0.0015+1.6%
1Server TTFT p50 (s)Single Run (1x)10020.09080.0917+0.0009+1.0%
2Server TTFT p50 (s)Single Run (1x)10040.16300.1623-0.0007-0.4%
3Server TTFT p50 (s)Single Run (1x)10080.31590.3127-0.0032-1.0%
4Server TTFT p50 (s)Single Run (1x)100160.31370.3135-0.0002-0.1%
5Server TTFT p50 (s)Single Run (1x)100320.31400.3137-0.0003-0.1%
6Server TTFT p50 (s)Single Run (1x)102410.09100.0917+0.0007+0.8%
7Server TTFT p50 (s)Single Run (1x)102420.16820.0912-0.0770-45.8%
8Server TTFT p50 (s)Single Run (1x)102440.15970.1310-0.0287-18.0%
9Server TTFT p50 (s)Single Run (1x)102480.31130.3144+0.0031+1.0%
10Server TTFT p50 (s)Single Run (1x)1024160.31290.3136+0.0007+0.2%
11Server TTFT p50 (s)Single Run (1x)1024320.31080.3143+0.0035+1.1%
34Server Tok/s p50Multi Run (10x)1001619.4161584.8025-34.6136-5.6%
35Server Tok/s p50Multi Run (10x)1002619.3149584.7465-34.5684-5.6%
36Server Tok/s p50Multi Run (10x)1004776.2750585.0394-191.2356-24.6%
37Server Tok/s p50Multi Run (10x)1008607.8911584.4519-23.4392-3.9%
38Server Tok/s p50Multi Run (10x)10016605.6483584.3005-21.3478-3.5%
39Server Tok/s p50Multi Run (10x)10032605.8772593.5173-12.3599-2.0%
40Server Tok/s p50Multi Run (10x)10241620.9225585.0422-35.8803-5.8%
41Server Tok/s p50Multi Run (10x)10242620.7307585.1295-35.6012-5.7%
42Server Tok/s p50Multi Run (10x)10244784.1768538.2166-245.9602-31.4%
43Server Tok/s p50Multi Run (10x)10248615.3324585.2877-30.0447-4.9%
44Server Tok/s p50Multi Run (10x)102416614.8655587.5843-27.2812-4.4%
45Server Tok/s p50Multi Run (10x)102432614.8678589.2794-25.5884-4.2%
24Server Tok/s p50Single Run (1x)1002619.2327583.6140-35.6187-5.8%
25Server Tok/s p50Single Run (1x)1004776.9642765.2556-11.7086-1.5%
26Server Tok/s p50Single Run (1x)1008609.0278588.3291-20.6987-3.4%
27Server Tok/s p50Single Run (1x)10016608.3037595.5981-12.7056-2.1%
28Server Tok/s p50Single Run (1x)10032605.6461594.1293-11.5168-1.9%
29Server Tok/s p50Single Run (1x)10242558.3128545.0032-13.3096-2.4%
30Server Tok/s p50Single Run (1x)10244783.9373527.9832-255.9541-32.6%
31Server Tok/s p50Single Run (1x)10248615.8302581.3243-34.5059-5.6%
32Server Tok/s p50Single Run (1x)102416615.4362593.4667-21.9695-3.6%
33Server Tok/s p50Single Run (1x)102432615.4209593.0451-22.3758-3.6%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Server metrics delta table — Encrypted minus Non-Encrypted\n", + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "df_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\n", + "df_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n", + "\n", + "server_metrics = [\n", + " ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n", + " ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n", + " ('server_end_to_end_latency_s_p50','Server E2E p50 (s)'),\n", + "]\n", + "\n", + "delta_rows = []\n", + "for col, label in server_metrics:\n", + " if col not in df_enc_s.columns:\n", + " continue\n", + " for idx in df_enc_s.index:\n", + " if idx not in df_plain_s.index:\n", + " continue\n", + " enc_val = df_enc_s.loc[idx, col]\n", + " plain_val = df_plain_s.loc[idx, col]\n", + " if pd.isna(enc_val) or pd.isna(plain_val):\n", + " continue\n", + " delta = enc_val - plain_val\n", + " pct_chg = delta / plain_val * 100 if plain_val != 0 else np.nan\n", + " delta_rows.append({\n", + " 'Metric': label,\n", + " 'Run Type': idx[0],\n", + " 'Output Tokens': idx[1],\n", + " 'Concurrency': idx[2],\n", + " 'Non-Encrypted': plain_val,\n", + " 'Encrypted': enc_val,\n", + " 'Delta': delta,\n", + " '% Change': pct_chg,\n", + " })\n", + "\n", + "df_server_delta = pd.DataFrame(delta_rows)\n", + "df_server_delta = df_server_delta.sort_values(['Metric', 'Run Type', 'Output Tokens', 'Concurrency'])\n", + "\n", + "def _pct_color(val):\n", + " if pd.isna(val): return ''\n", + " if val > 50: return 'background-color: #ffaaaa'\n", + " if val > 20: return 'background-color: #ffd8aa'\n", + " if val > 0: return 'background-color: #fffacc'\n", + " if val < -20: return 'background-color: #aaffaa'\n", + " return ''\n", + "\n", + "df_server_delta.style \\\n", + " .applymap(_pct_color, subset=['% Change']) \\\n", + " .format({\n", + " 'Non-Encrypted': '{:.4f}',\n", + " 'Encrypted': '{:.4f}',\n", + " 'Delta': '{:+.4f}',\n", + " '% Change': '{:+.1f}%',\n", + " })" + ] + }, + { + "cell_type": "markdown", + "id": "cell-tee-hdr", + "metadata": {}, + "source": [ + "## 4. TEE Overhead Decomposition (Encrypted Model Only)\n", + "\n", + "Three measurable components are returned by the TEE per request:\n", + "\n", + "| Component | Description | Expected Behavior |\n", + "|-----------|-------------|-------------------|\n", + "| **Input Encryption** | Time to encrypt the prompt before sending to server | ~constant, independent of output length |\n", + "| **Output Decryption** | Cumulative time to decrypt all streaming output chunks | grows with output token count |\n", + "| **Network Hop** | Round-trip latency through the TEE (Client→TEE→Server→TEE→Client) | grows with concurrency (TEE queue) and output tokens |\n", + "\n", + "> The network hop is the dominant overhead. At high concurrency it grows due to TEE core saturation." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "cell-tee-stack", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Component=Network Hop
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "tF/Sc2b28D9iYpi4+lbqPx/oVynzheU/ANsLFphf7D8h+v+C7vzwP3xfXKrStv0/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Network Hop
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "fv0QGywc0D+ZG8LnPeT9P/tTT4tmKgNAMJXIT/TaCUBQr+8e+6wRQPMKnwg9ZhpA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Input Encryption
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "EHLe/8cJcz9bVNUVfU92PyZ/QRw1cHE/fuNrzywJcD9TZ6SUxh5wP6yn+6Xqw28/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Input Encryption
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "3/jaM0sCdD/xFTg0wGByP4FRkyqbg3E/E91pIbcVcT/c4J+t3jxwP01/m2rSEnA/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Output Decryption
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "aDXJND+jGT/MvLCQFOxKP+kj8Ief/z4/9uEP9XEjOz/cjl8umK42Px8ZBody/TY/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Output Decryption
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "BbqbTIFxFT8kmA+turNrP5a4jnHFxXE/Nms6TEV0aT8kWpe/5yxoPy9WLxqN12c/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Network Hop
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "W+jvSjcu2z+40bZQ6CvhP9BwubAkL+M/Da2ph8Nt5D+MQjegSjLoP6e4BaYutOk/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Network Hop
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "fdCzWfW5+T9Fxv4NNXUDQLFiXYGN4AVALINqgxMhAkC67lKP2W4FQFafBmdLMQlA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Component=Input Encryption
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ddQsK6gDhD+naQan9AKCPyctXFZhM4A/CghSzrzBfD9ZcQVvo1x1PwFsQIS4cnY/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Input Encryption
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "EhJpG3+igj8Qj8TL07mCP0F/Ro4ZTYM/gVlGj4Qigj8QWg9fJoqAPzQary/ITHg/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Component=Output Decryption
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "MO6rF+h/bj/IuhNHeUFfPzfvSXGfZlI/LGdKRil8UT/HMe32tB5JP/HfF/JjJ0c/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Output Decryption
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "gJ9x4UBIhj90Ge2ntR9/P5vPFJVoJH0/UsGXePZLej9iqHl9nB91PyHyTB4FPnU/", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "stack", + "height": 700, + "legend": { + "title": { + "text": "Component" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Overhead Breakdown per Request (Encrypted Model Only)
Network Hop dominates. Encryption is near-constant. Decryption scales with output token count (streaming per-chunk decryption)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.48 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Overhead (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Overhead (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_tee = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "\n", + "# Convert ms → s for consistent units with latency charts\n", + "df_tee['Network Hop'] = df_tee['server_network_latency_ms_mean'] / 1000\n", + "df_tee['Input Encryption'] = df_tee['total_encryption_time_ms_mean'] / 1000\n", + "df_tee['Output Decryption'] = df_tee['total_decryption_time_ms_mean'] / 1000\n", + "\n", + "TEE_ID_COLS = ['run_type', 'out_tokens_label', 'num_concurrent_requests']\n", + "TEE_VAL_COLS = ['Network Hop', 'Input Encryption', 'Output Decryption']\n", + "\n", + "df_tee_melt = df_tee[TEE_ID_COLS + TEE_VAL_COLS].melt(\n", + " id_vars=TEE_ID_COLS, var_name='Component', value_name='Overhead (s)'\n", + ")\n", + "\n", + "COMP_COLORS = {\n", + " 'Network Hop': '#FF7F0E',\n", + " 'Input Encryption': '#D62728',\n", + " 'Output Decryption': '#2CA02C',\n", + "}\n", + "\n", + "fig = px.bar(\n", + " df_tee_melt,\n", + " x='num_concurrent_requests',\n", + " y='Overhead (s)',\n", + " color='Component',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='stack',\n", + " color_discrete_map=COMP_COLORS,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'run_type': 'Run Type',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " },\n", + " title=(\n", + " 'TEE Overhead Breakdown per Request (Encrypted Model Only)
'\n", + " 'Network Hop dominates. Encryption is near-constant. '\n", + " 'Decryption scales with output token count (streaming per-chunk decryption).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "cell-network-latency", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Output Tokens=100 output tokens
Run Type=Single Run (1x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "100 output tokens, Single Run (1x)", + "line": { + "color": "#636efa", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "100 output tokens, Single Run (1x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "dnEbDaCQkEAU0ETY8LiJQK7YX3bPBIVA3pOHhVq1i0BE+u3rAJeQQD81XrqJBJ1A", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Run Type=Multi Run (10x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "100 output tokens, Multi Run (10x)", + "line": { + "color": "#636efa", + "dash": "dash" + }, + "marker": { + "symbol": "diamond" + }, + "mode": "lines+markers", + "name": "100 output tokens, Multi Run (10x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "6Ugu/yGLekDOiNLe4MSAQCsYldQJvIJA/7J78jDzg0D99nXgHKGHQFOWIY71GYlA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Run Type=Single Run (1x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "1024 output tokens, Single Run (1x)", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "1024 output tokens, Single Run (1x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "Gy/dJAZ3b0DzjlN05DCdQAN4CyRot6JAseHpldI/qUA0ETY87UKxQLFQa5rXx7lA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Run Type=Multi Run (10x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "1024 output tokens, Multi Run (10x)", + "line": { + "color": "#EF553B", + "dash": "dash" + }, + "marker": { + "symbol": "diamond" + }, + "mode": "lines+markers", + "name": "1024 output tokens, Multi Run (10x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "mpmZmZkfmUCfzarPdQCjQGEyVTBKXaVAGQRWDk20oUAi/fZ1QO6kQJp3nKIjmqhA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.245, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.755, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 450, + "legend": { + "title": { + "text": "Output Tokens, Run Type" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Network Latency vs Concurrency
Solid = Single Run (1x) | Dashed = Multi Run (10x). Grows with concurrency (TEE queueing) AND with output tokens (streaming: each decrypted chunk adds a network round-trip)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.49 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.51, + 1 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "TEE Network Latency — Mean (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Network latency growth — most important overhead component\n", + "fig = px.line(\n", + " df_tee,\n", + " x='num_concurrent_requests',\n", + " y='server_network_latency_ms_mean',\n", + " color='out_tokens_label',\n", + " symbol='run_type',\n", + " line_dash='run_type',\n", + " line_dash_map={'Single Run (1x)': 'solid', 'Multi Run (10x)': 'dash'},\n", + " facet_col='out_tokens_label',\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_network_latency_ms_mean': 'TEE Network Latency — Mean (ms)',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'TEE Network Latency vs Concurrency
'\n", + " 'Solid = Single Run (1x) | Dashed = Multi Run (10x). '\n", + " 'Grows with concurrency (TEE queueing) AND with output tokens '\n", + " '(streaming: each decrypted chunk adds a network round-trip).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=450, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "cell-enc-dec-times", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "legendgroup": "100 out | Single Run (1x)", + "line": { + "color": "#1f77b4", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "100 out | Single Run (1x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ZDvfT42XEkBhVFInoMkVQCv2l92TBxFAUrgehetRD0DOGVHaG3wPQL7BFyZTBQ9A", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "100 out | Single Run (1x)", + "line": { + "color": "#1f77b4", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "100 out | Single Run (1x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "KH6MuWsJuT9fmEwVjErqPxKDwMqhRd4/qoJRSZ2A2j+DUUmdgCbWP4j029eBc9Y/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "legendgroup": "1024 out | Single Run (1x)", + "line": { + "color": "#ff7f0e", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "1024 out | Single Run (1x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "CtejcD2KE0Btxf6ye/IRQJjdk4eFGhFA5WGh1jSvEEAtQxzr4rYPQKK0N/jCZA9A", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "1024 out | Single Run (1x)", + "line": { + "color": "#ff7f0e", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "1024 out | Single Run (1x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "qRPQRNjwtD+TOgFNhA0LQEJg5dAiWxFAswxxrIvbCEAHzhlR2psHQCo6kst/SAdA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "legendgroup": "100 out | Multi Run (10x)", + "line": { + "color": "#1f77b4", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "100 out | Multi Run (10x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "escpOpKLI0AtQxzr4pYhQDEIrBxapB9A2ht8YTIVHECxUGuad9wUQHnpJjEI7BVA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "100 out | Multi Run (10x)", + "line": { + "color": "#1f77b4", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "100 out | Multi Run (10x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "m+Ydp+jIDUBnRGlv8IX+P5wzorQ3+PE/waikTkAT8T+coiO5/IfoP7FQa5p3nOY/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "legendgroup": "1024 out | Multi Run (10x)", + "line": { + "color": "#ff7f0e", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "1024 out | Multi Run (10x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ppvEILAyIkC28/3UeEkiQEXY8PRK2SJAaLPqc7W1IUD0/dR46SYgQJf/kH77uhdA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "1024 out | Multi Run (10x)", + "line": { + "color": "#ff7f0e", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "1024 out | Multi Run (10x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "w/UoXI/CJUDbiv1l92QeQL1SliGOdRxAyjLEsS6uGUBwzojS3qAUQHQkl/+QvhRA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Input Encryption Time (ms)", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Output Decryption Time (ms)", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 420, + "legend": { + "title": { + "text": "out tokens | run type" + } + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Encryption & Decryption Times
Encryption is near-constant (~4-10 ms). Decryption grows with output token count; decreases at higher concurrency as TEE queue pressure compresses per-request wall time." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.45 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.55, + 1 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Time (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Time (ms)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Encryption and decryption times detail\n", + "fig = make_subplots(\n", + " rows=1, cols=2,\n", + " subplot_titles=['Input Encryption Time (ms)', 'Output Decryption Time (ms)'],\n", + ")\n", + "\n", + "_run_styles = {'Single Run (1x)': 'solid', 'Multi Run (10x)': 'dash'}\n", + "_tok_colors = {100: '#1f77b4', 1024: '#ff7f0e'}\n", + "_shown = set()\n", + "\n", + "for run_type, dash in _run_styles.items():\n", + " for out_tok, color in _tok_colors.items():\n", + " sub = df_tee[(df_tee['run_type'] == run_type) & (df_tee['num_output_tokens'] == out_tok)]\n", + " name = f'{out_tok} out | {run_type}'\n", + " show = name not in _shown\n", + " kw = dict(x=sub['num_concurrent_requests'], mode='lines+markers',\n", + " name=name, line=dict(color=color, dash=dash),\n", + " legendgroup=name, showlegend=show)\n", + " fig.add_trace(go.Scatter(y=sub['total_encryption_time_ms_mean'], **kw), row=1, col=1)\n", + " kw['showlegend'] = False\n", + " fig.add_trace(go.Scatter(y=sub['total_decryption_time_ms_mean'], **kw), row=1, col=2)\n", + " _shown.add(name)\n", + "\n", + "fig.update_xaxes(\n", + " type='log', tickvals=CONC_ORDER, ticktext=CONC_STR,\n", + " title_text='Concurrency (log scale)',\n", + ")\n", + "fig.update_yaxes(title_text='Time (ms)', col=1)\n", + "fig.update_yaxes(title_text='Time (ms)', col=2)\n", + "fig.update_layout(\n", + " height=420, width=1100, template='plotly_white',\n", + " legend_title='out tokens | run type',\n", + " title=(\n", + " 'TEE Encryption & Decryption Times
'\n", + " 'Encryption is near-constant (~4-10 ms). '\n", + " 'Decryption grows with output token count; decreases at higher concurrency '\n", + " 'as TEE queue pressure compresses per-request wall time.'\n", + " ),\n", + ")\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "id": "cell-client-hdr", + "metadata": {}, + "source": [ + "## 5. Client-Side Metrics — End-User Experience\n", + "\n", + "Client metrics include the full roundtrip: **Client → (TEE) → Server → (TEE) → Client**.\n", + "\n", + "The gap between encrypted and non-encrypted client metrics is the\n", + "**observable user-facing cost** of the TEE encryption layer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-client-ttft", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='out_tokens_label',\n facet_row='run_type',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_ttft_s_p50': 'Client TTFT p50 (s)',\n 'label': 'Model',\n 'out_tokens_label': 'Output Tokens',\n 'run_type': 'Run Type',\n },\n title=(\n 'Client Time to First Token — p50
'\n 'At concurrency 1–8: encrypted is slower due to TEE network overhead. '\n 'At concurrency ≥ 16 (100 tokens): encrypted TTFT drops below non-encrypted — '\n 'the TEE de-batching advantage on the server (lower prefill time) outweighs '\n 'the network overhead, flipping the comparison. This crossover does not appear '\n 'for 1,024 tokens where network overhead is larger and dominates.'\n ),\n)\nfig.update_layout(height=700, width=1100, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "cell-ttft-attribution", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Component=Network Hop (s)
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop (s)", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "tF/Sc2b28D9iYpi4+lbqPx/oVynzheU/ANsLFphf7D8h+v+C7vzwP3xfXKrStv0/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Network Hop (s)
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop (s)", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "fv0QGywc0D+ZG8LnPeT9P/tTT4tmKgNAMJXIT/TaCUBQr+8e+6wRQPMKnwg9ZhpA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Input Encryption (s)
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption (s)", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "EHLe/8cJcz9bVNUVfU92PyZ/QRw1cHE/fuNrzywJcD9TZ6SUxh5wP6yn+6Xqw28/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Input Encryption (s)
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption (s)", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "3/jaM0sCdD/xFTg0wGByP4FRkyqbg3E/E91pIbcVcT/c4J+t3jxwP01/m2rSEnA/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Output Decryption (s)
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption (s)", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "aDXJND+jGT/MvLCQFOxKP+kj8Ief/z4/9uEP9XEjOz/cjl8umK42Px8ZBody/TY/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Output Decryption (s)
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption (s)", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "BbqbTIFxFT8kmA+turNrP5a4jnHFxXE/Nms6TEV0aT8kWpe/5yxoPy9WLxqN12c/", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Residual (s)
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Residual (s)", + "marker": { + "color": "#9467BD", + "pattern": { + "shape": "" + } + }, + "name": "Residual (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Component=Residual (s)
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Residual (s)", + "marker": { + "color": "#9467BD", + "pattern": { + "shape": "" + } + }, + "name": "Residual (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Component=Network Hop (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop (s)", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "W+jvSjcu2z+40bZQ6CvhP9BwubAkL+M/Da2ph8Nt5D+MQjegSjLoP6e4BaYutOk/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Network Hop (s)
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop (s)", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "fdCzWfW5+T9Fxv4NNXUDQLFiXYGN4AVALINqgxMhAkC67lKP2W4FQFafBmdLMQlA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Component=Input Encryption (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption (s)", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ddQsK6gDhD+naQan9AKCPyctXFZhM4A/CghSzrzBfD9ZcQVvo1x1PwFsQIS4cnY/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Input Encryption (s)
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption (s)", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "EhJpG3+igj8Qj8TL07mCP0F/Ro4ZTYM/gVlGj4Qigj8QWg9fJoqAPzQary/ITHg/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Component=Output Decryption (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption (s)", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "MO6rF+h/bj/IuhNHeUFfPzfvSXGfZlI/LGdKRil8UT/HMe32tB5JP/HfF/JjJ0c/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Output Decryption (s)
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption (s)", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "gJ9x4UBIhj90Ge2ntR9/P5vPFJVoJH0/UsGXePZLej9iqHl9nB91PyHyTB4FPnU/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Component=Residual (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Residual (s)", + "marker": { + "color": "#9467BD", + "pattern": { + "shape": "" + } + }, + "name": "Residual (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Residual (s)
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Residual (s)", + "marker": { + "color": "#9467BD", + "pattern": { + "shape": "" + } + }, + "name": "Residual (s)", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "stack", + "height": 700, + "legend": { + "title": { + "text": "Component" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta
Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. Residual = delta not fully explained by TEE metrics (measurement noise / base model diff)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.48 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Overhead (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Overhead (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Client TTFT overhead attribution: stacked TEE components vs total delta\n", + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "df_enc_a = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "df_plain_a = df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n", + " columns={'client_ttft_s_p50': 'client_ttft_plain'}\n", + ")\n", + "df_attr = df_enc_a.merge(df_plain_a, on=DIMS)\n", + "\n", + "df_attr['client_ttft_delta'] = df_attr['client_ttft_s_p50'] - df_attr['client_ttft_plain']\n", + "df_attr['Network Hop (s)'] = df_attr['server_network_latency_ms_mean'] / 1000\n", + "df_attr['Input Encryption (s)']= df_attr['total_encryption_time_ms_mean'] / 1000\n", + "df_attr['Output Decryption (s)']= df_attr['total_decryption_time_ms_mean'] / 1000\n", + "df_attr['Residual (s)'] = (\n", + " df_attr['client_ttft_delta']\n", + " - df_attr['Network Hop (s)']\n", + " - df_attr['Input Encryption (s)']\n", + " - df_attr['Output Decryption (s)']\n", + ").clip(lower=0)\n", + "df_attr['out_tokens_label'] = df_attr['num_output_tokens'].astype(str) + ' output tokens'\n", + "\n", + "ATTR_COLS = ['Network Hop (s)', 'Input Encryption (s)', 'Output Decryption (s)', 'Residual (s)']\n", + "ATTR_COLORS = {\n", + " 'Network Hop (s)': '#FF7F0E',\n", + " 'Input Encryption (s)': '#D62728',\n", + " 'Output Decryption (s)':'#2CA02C',\n", + " 'Residual (s)': '#9467BD',\n", + "}\n", + "\n", + "df_attr_melt = df_attr.melt(\n", + " id_vars=['run_type', 'out_tokens_label', 'num_concurrent_requests', 'client_ttft_delta'],\n", + " value_vars=ATTR_COLS, var_name='Component', value_name='Overhead (s)',\n", + ").dropna(subset=['Overhead (s)'])\n", + "\n", + "fig = px.bar(\n", + " df_attr_melt,\n", + " x='num_concurrent_requests',\n", + " y='Overhead (s)',\n", + " color='Component',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='stack',\n", + " color_discrete_map=ATTR_COLORS,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'run_type': 'Run Type',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " },\n", + " title=(\n", + " 'Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta
'\n", + " 'Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. '\n", + " 'Residual = delta not fully explained by TEE metrics (measurement noise / base model diff).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "cell-client-e2e", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "MLsnDwu18j9PQBNhw9PtP0I+6Nms+uo/KxiV1Alo8T9pAG+BBMXyP8X+snvysP4/", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "9GxWfa621j9EaW/whcn/P23F/rJ7cgRAMzMzMzOzC0A4+MJkqiASQFYOLbKdrxpA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "vp8aL90k4D+TOgFNhA3lP86qz9VW7OU/VTAqqRPQ6j+HFtnO91PpPwKaCBueXu0/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "BaOSOgFNAEC30QDeAokFQPwYc9cS8glA6+I2GsDbD0CU9gZfmIwQQAisHFpkuxNA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "p3nHKTqS4z+4rwPnjCjhPyv2l92Th+s/ArwFEhQ/8D8dyeU/pN/xPyV1ApoIGwJA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "qMZLN4lB/T9a9bnaiv0AQPvL7snDQvM/RiV1ApoIC0Btxf6ye/IMQAaBlUOLLBRA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "3EYDeAsk2D+5jQbwFkjkP1fsL7snD+U/KjqSy39I6z+xv+yePCzxP6g1zTtOUQFA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "I0p7gy9M/T/UK2UZ4tgMQPOOU3QkFwdAVFInoIkwCkD35GGh1rQHQBZqTfOO0xdA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client End-to-End Latency — p50
Full request duration as observed by the client. Grows faster for encrypted at high concurrency due to TEE queueing." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.48 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Client E2E Latency p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Client E2E Latency p50 (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_end_to_end_latency_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_end_to_end_latency_s_p50': 'Client E2E Latency p50 (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client End-to-End Latency — p50
'\n", + " 'Full request duration as observed by the client. '\n", + " 'Grows faster for encrypted at high concurrency due to TEE queueing.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "cell-client-toks", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAA+H+SXP5D+q6CQM4ZUdobk4hAoBov3SSRgkBI4XoUrneDQIbJVMGo5YJA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "AAAAAAAA+H9lqmBUUjiBQIZa07xjhIBAjNtoAG85gkBPHhZqzZKCQEJg5dCij4JA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "nDOitDdxgkCVZYhj3YWCQBE2PL1SiYJAEoPAyqGKgkDLoUW2c5GCQMdLN4lBBINA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "OwFNhI1FgkBJnYAmQkyCQPW52op9RoJAgy9MpopjgkDcRgN4i2aCQMUgsHLofoJA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "zF1LyAeAg0C3Yn/ZvaeDQMrDQq3pdohAKxiV1Al9g0AVjErqBBuDQLsnDwu1UoNA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "Ns07TlFvg0AqOpLLf3aBQFfsL7snhIhAOpLLf8hBg0Do2az63D6DQD9XW7E/R4NA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "aCJseHqtg0BU46WbxKODQFUwKqkTTYhAxY8xdy0gg0Dl0CLb+SKDQAisHFpkHYNA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "V+wvuydrg0DwFkhQ/GuDQKTfvg6ciIhAPZtVnytDg0DFjzF3LUODQDarPlfbPYNA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client Output Throughput per Request — p50
After the first token, subsequent tokens stream at this rate. Encrypted is limited by TEE streaming decryption speed; Non-Encrypted is limited by server generation speed at high concurrency." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.48 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Client Output Tok/s p50 (per request)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Client Output Tok/s p50 (per request)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Per-request client generation speed\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_output_token_per_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_output_token_per_s_p50': 'Client Output Tok/s p50 (per request)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client Output Throughput per Request — p50
'\n", + " 'After the first token, subsequent tokens stream at this rate. '\n", + " 'Encrypted is limited by TEE streaming decryption speed; '\n", + " 'Non-Encrypted is limited by server generation speed at high concurrency.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "cell-total-throughput", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAA0gLdAgsBmQGkAb4EEeHRAw/UoXI+GfEAdWmQ735SDQI/C9Sjc34tA", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "AAAAAAAAAAAYJlMFo5N7QGHD0ytl14RAhA1Pr5SKk0D/snvy8NubQCZTBaOS6aBA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "rthfdk/kZkAbL90kBtVuQO5aQj7owUJAXdxGA3hTSUAs1JrmHVdFQIbJVMGoPEJA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "gLdAguJtfUCGWtO848KAQD0K16PwU4NAhlrTvOPpdkCx4emVskJ0QMRCrWneSXZA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "pSxDHOtGZEBbQj7o2d1xQO2ePCzUuHxANKK0N3gkiEBGlPYGX7KNQMl2vp+aDI9A", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x4", + "y": { + "bdata": "NV66SQxrgUBdbcX+MuyNQEi/fR34D5BAuY0G8NaemkC4HoXr0S6hQNDVVuxPlKVA", + "dtype": "f8" + }, + "yaxis": "y4" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "1CtlGeLib0BIUPwYc2ZzQFK4HoXroYJALUMc6+KijECRD3o2a9uVQMNkqmBUF5ZA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQIECBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "CKwcWmRfgUD+ZffkYSaEQGUZ4ljXmJBAwTkjSvt/m0BfB84ZceOqQBHHurjtwqtA", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Total Client Output Throughput — All Concurrent Requests
Non-Encrypted scales nearly linearly with concurrency. Encrypted collapses at higher concurrencies due to TEE queuing adding large wall-clock delays." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.48 + ], + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "ticktext": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 2, + 4, + 8, + 16, + 32 + ], + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Total Output Throughput (tok/s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Total Output Throughput (tok/s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Total system throughput — aggregate across all concurrent requests\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_total_output_throughput',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_total_output_throughput': 'Total Output Throughput (tok/s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Total Client Output Throughput — All Concurrent Requests
'\n", + " 'Non-Encrypted scales nearly linearly with concurrency. '\n", + " 'Encrypted collapses at higher concurrencies due to TEE queuing adding large wall-clock delays.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "id": "cell-dist-hdr", + "metadata": {}, + "source": [ + "## 6. Per-Request Distributions\n", + "\n", + "Box plots using individual request data from all runs.\n", + "- **Multi Run (10x)** provides the richest distributions (10–320 requests per scenario across 10 rounds).\n", + "- **Single Run (1x)** covers only the N simultaneous requests in a single round (1–32 points per box depending on concurrency).\n", + "\n", + "Error requests (where `error_code` is set) are excluded." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "cell-load-individual", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 2,621 individual request records\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
count
labelrun_typeis_error
EncryptedSingle Run (1x)False126
Multi Run (10x)False1109
Non-EncryptedSingle Run (1x)False126
Multi Run (10x)False1260
\n", + "
" + ], + "text/plain": [ + " count\n", + "label run_type is_error \n", + "Encrypted Single Run (1x) False 126\n", + " Multi Run (10x) False 1109\n", + "Non-Encrypted Single Run (1x) False 126\n", + " Multi Run (10x) False 1260" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def _parse_fname(fname):\n", + " \"\"\"Extract (out_tokens, concurrency) from benchmark filename.\"\"\"\n", + " base = os.path.basename(str(fname)).replace('_individual_responses.json', '')\n", + " parts = base.split('_')\n", + " try:\n", + " return int(parts[4]), int(parts[5])\n", + " except (IndexError, ValueError):\n", + " return None, None\n", + "\n", + "dfs_ind = []\n", + "for key, meta in DATASETS.items():\n", + " try:\n", + " df_ind = read_perf_eval_json_files(meta['run_dir'], type='individual_responses')\n", + " if df_ind.empty:\n", + " continue\n", + " df_ind['label'] = meta['label']\n", + " df_ind['run_type'] = meta['run_type']\n", + " parsed = df_ind['filename'].apply(lambda f: pd.Series(_parse_fname(f)))\n", + " df_ind['num_output_tokens'] = parsed[0]\n", + " df_ind['num_concurrent_requests'] = parsed[1]\n", + " dfs_ind.append(df_ind)\n", + " except Exception as e:\n", + " print(f'Warning: could not load {key}: {e}')\n", + "\n", + "df_individual = pd.concat(dfs_ind, ignore_index=True)\n", + "df_individual = df_individual.dropna(\n", + " subset=['num_output_tokens', 'num_concurrent_requests', 'client_ttft_s']\n", + ")\n", + "df_individual['num_output_tokens'] = df_individual['num_output_tokens'].astype(int)\n", + "df_individual['num_concurrent_requests'] = df_individual['num_concurrent_requests'].astype(int)\n", + "df_individual['out_tokens_label'] = df_individual['num_output_tokens'].astype(str) + ' output tokens'\n", + "df_individual['concurrency_str'] = df_individual['num_concurrent_requests'].astype(str)\n", + "df_individual['is_error'] = df_individual['error_code'].notna()\n", + "df_individual['run_type'] = pd.Categorical(\n", + " df_individual['run_type'],\n", + " categories=['Single Run (1x)', 'Multi Run (10x)'],\n", + " ordered=True\n", + ")\n", + "\n", + "print(f'Loaded {len(df_individual):,} individual request records')\n", + "df_individual.groupby(['label', 'run_type', 'is_error'])[['client_ttft_s']].count().rename(\n", + " columns={'client_ttft_s': 'count'}\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "cell-box-client-ttft", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "4", + "4", + "4", + "4", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "2", + "2" + ], + "x0": " ", + "xaxis": "x3", + "y": { + "bdata": "OY7jE8t12D/PfAUK7+flP01Z0zjZz+U/iUU0RdZNBkAAAACqfbbWP/jXgTlgIt4/TLal18Sk3j8AAOAUruMFQCd2ynoc1wVAm9VSu3zWBUBpg3uRCNwFQAamFPzJ0AVA4nlI/VzyBUCjVzACfPjfPyhSvfCjMOA/AAAwLSCdBkBsKD+yZaQGQIy3jwL/lgZAEHPil4yiBkDSMOECpKIGQH5QKg7BoQZAkYVUUEq4BkDy2FugTq8GQAAAcOjrqxNAAAAg59XBE0DKGmlyVacTQAqn2m3/rRNA3K5zn1q6E0CSTg4qbbYTQBME4x075OI/a8BInJUS4z8AAFCr/WoHQAAAAFH8egdAvRNQk39SB0C5sJCcT3AHQMuuxpA+egdA60z/Zbg4B0BQmmi40WMHQCprOlSJcwdAAAA4M+EMFECo/aIZ2RAUQMGuIkvD+RNAjyBb/E8HFECQC6PMUQMUQHZZzs6oBBRAQ4J/mz4bFED3ABfvlRAUQEmS7rZ+fhxAiU9QuS9cHEDsupxnR3YcQCDxTKh+cRxAHEfNe0ZmHEAuh+MTYVocQNi3VD6sVxxAegCiQMFqHEAAAEBNkmQiQDMzOytpWCJASXuEiw5nIkAwhB4uoW0iQAzpOuAXYSJAwvDfoxRfIkB5VlS4NZnWPz4yAapPkf8/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "4", + "4", + "4", + "4" + ], + "x0": " ", + "xaxis": "x4", + "y": { + "bdata": "T+zExb284z9iJ55zkIrjPwAAQCavEfM/AADgA8EE8z9P7IA78fzyPwAADHVz+PI/ip30KJEu8z+e2Imoc+PyP7ETj3JYN/M/dmJ7JLbS8j/Zia2Hw8n7P0/s8LkYw/s/sRPvRHuX+z/ZidGRkfv7P+zEPkmC4vs/xU6Mvpqq+z87sdOsuBj8Pzux2245Ufw/AADQwRHHAkAREUGJ5DACQE/s4kZPOAJAFDvR/LbPAkB2Yh2rcuoCQLET3XrcNwJAdmJtlI6nAkDZibnizKcCQAAAYHSZ1QZAip3ongjBBkAndvpsCKoGQMVOVpHd1AZAnthDeq3NBkCxEwUrqbsGQOzE7jQRJeA/O7FbP3UR4D+xE5PO+obgPwAAIOexO/A/AACACEAS8D8AAEBcPyXwP9mJbcDuJ/A/FDtVmyzD8D8ndoruFUXwPxQ72Y+zG/A/FDshsdld8D8AAEBnruD4PwAAYJTA+fg/YieWl2BB+T92Ym+ErxD5PxQ78Z5JQvk/AAAgsCm18j/ZiT1Sz/fYPwAAgBXKnO4/AACA2R7g7j+rqurJl6jvP4qdiInLgO4/L6fAVBW/7j/FTmz+eIfvP4qdoHW4mu4/FDtJoF0t4z9iJzZII8btP7ETe/v4Xdg/AADAa+YJ6T/sxKblYeLoP0/sNFoyHek/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "4", + "4", + "4", + "4" + ], + "x0": " ", + "xaxis": "x3", + "y": { + "bdata": "twphjKuV3T8u5wLniQMEQN2IryJ6/QNAEvaNh5WlA0A0H0SXPO4DQPhS+4cs6wNA8xoyU5faA0B1I64TCwkEQLDIHb4d+wNAX2o6BCF/D0AN5X1GN1YPQFA30pX5Uw9AI57haSm6D0DEM8/uBaEPQIIIlLFpxg9AUDcaIMCOD0D9uUFSvfnOPxfgVMKuJAJAymsok1MsAkC0slRpoQ4CQNYCTJQhGQJALcCRg180AkAwNV0l8SoCQJYlM5z4GgJAIsbAyJOx0j80TEB2GJrSP46p6HOdS8c/XaPmi08i2z990JID4psDQD5BnFlMfwNAaD4osfeRA0CaD9LTa3sDQKBHMx4PlwNANW1WYr2YA0Ajd7Al4Y0DQOFLvf2jmgNA/WPLq3ozD0Bm8K0yD3oPQBCBak5uKA9ATXR07ZkSD0CMKgRTTv0OQM984ERsVQ9A1gIk5vkVD0DmXDX4qgIPQJs2J7JoQRVAwXD1laZrFUBHPEffMmAVQPbdq4T+/hRAio73+39aFUA34kFs3i4VQIq1pEEnwxRALucSsnccFUB90A7HFwAbQE8QuYRtSxtANEYB0usMG0BoZfHy8c8aQBa5L6Iw0hpAp83qjvQzG0D0aMzFHe0aQHKH2RmcA9U/9Y9tEhX91D+2ACeMrNjUPxkNU3W/lfU/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "2", + "2", + "4", + "4", + "4", + "4", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32" + ], + "x0": " ", + "xaxis": "x4", + "y": { + "bdata": "Yie2AN7Tyz/Zic0IVy/hP+zEXtqoGNY/J3aK8LeH5z92YjfIx3PnP9mJFcxSbuc/ip24Z2/i3D8AAICxtaPTP8VO9BH+pOs/sRPb2hvi6j8ndnr1S23rP8VOJBHFPus/J3ZKuGce6z8ndqLhJZzrP0/s3CDqius/sROLOQc+2j+xExsGs5nuP+zETl5lZe4/T+wUIs947j+KnaiGGADuPwAA0FPNp+4/2YkVuuda7T+e2IlE6LHsP3ZiN/CiPu4/YieqPq569z/FTkCh87j2P57YqbYh5fc/xU5oaG0C9z+KnTCu4Gb3PwAAML6+0Pc/Yifaag2s9z8ndsr7ra3kPzux236xKPE/7MR+2ZxQ8T+e2DUNoCbyP4qdTJJoI/E/J3YKGDGv7T/FTvwVqpfyP2InekDjDvc/YidS2eaL9z87sQMnn9r3Pyd21qwJKvk/ip0EFekS+D92Yod7aVP4P0/sLA7offg/xU4IO3sC9z8ndgSuJ3cBQMVO9rsFgAFAYicI37B4AUAUO7dKroMBQAAAmLiDCwFAxU603wWyAECKndoOdjgBQJ7YS8YO4QBAAACmmMGdBUAAAHA/bmgEQCd2lmAAVwRAFDuliH2nBEBiJ6rQS1oEQBQ7W9sVtgRAFDu/KKRdBEAnduoY73wEQHZih/gf2QdA", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2" + ], + "x0": " ", + "xaxis": "x2", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y2" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1" + ], + "x0": " ", + "xaxis": "x2", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "boxmode": "group", + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client TTFT Distribution per Concurrency
Encrypted shows higher median AND wider spread due to variable TEE network latency. High concurrency increases spread (TEE queue wait time variance)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0, + 0.48 + ], + "title": { + "text": "Concurrency" + } + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + } + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Client TTFT (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Client TTFT (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_box = df_individual[~df_individual['is_error']].copy()\n", + "\n", + "fig = px.box(\n", + " df_box,\n", + " x='concurrency_str',\n", + " y='client_ttft_s',\n", + " color='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'concurrency_str': CONC_STR,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " points='outliers',\n", + " labels={\n", + " 'concurrency_str': 'Concurrency',\n", + " 'client_ttft_s': 'Client TTFT (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label':'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client TTFT Distribution per Concurrency
'\n", + " 'Encrypted shows higher median AND wider spread due to variable TEE network latency. '\n", + " 'High concurrency increases spread (TEE queue wait time variance).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "cell-box-server-ttft", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "4", + "4", + "4", + "4", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "2", + "2" + ], + "x0": " ", + "xaxis": "x3", + "y": { + "bdata": "AAAAANCbtz8AAAAAULzFPwAAAABQvMU/AAAAAHBBtz8AAAAAoHi3PwAAAABgQsU/AAAAAGBCxT8AAAAAkx7UPwAAAACTHtQ/AAAAAJMe1D8AAAAAkx7UPwAAAACTHtQ/AAAAAJMe1D8AAAAATmTFPwAAAABOZMU/AAAAAHwa1D8AAAAAfBrUPwAAAAB8GtQ/AAAAAHwa1D8AAAAAfBrUPwAAAAB8GtQ/AAAAAHwa1D8AAAAAfBrUPwAAAAA+CtQ/AAAAAD4K1D8AAAAAPgrUPwAAAAA+CtQ/AAAAAD4K1D8AAAAAPgrUPwAAAAAgccU/AAAAACBxxT8AAAAArj3UPwAAAACuPdQ/AAAAAK491D8AAAAArj3UPwAAAACuPdQ/AAAAAK491D8AAAAArj3UPwAAAACuPdQ/AAAAALEp1D8AAAAAsSnUPwAAAACxKdQ/AAAAALEp1D8AAAAAsSnUPwAAAACxKdQ/AAAAALEp1D8AAAAAsSnUPwAAAADnANQ/AAAAAOcA1D8AAAAA5wDUPwAAAADnANQ/AAAAAOcA1D8AAAAA5wDUPwAAAADnANQ/AAAAAOcA1D8AAAAA8A/UPwAAAADwD9Q/AAAAAPAP1D8AAAAA8A/UPwAAAADwD9Q/AAAAAPAP1D8AAAAAHEG3PwAAAABEbbc/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "4", + "4", + "4", + "4" + ], + "x0": " ", + "xaxis": "x4", + "y": { + "bdata": "AAAAAKBkxT8AAAAAoGTFPwAAAACfDdQ/AAAAAJ8N1D8AAAAAnw3UPwAAAACfDdQ/AAAAAJ8N1D8AAAAAnw3UPwAAAACfDdQ/AAAAAJ8N1D8AAAAAIhzUPwAAAAAiHNQ/AAAAACIc1D8AAAAAIhzUPwAAAAAiHNQ/AAAAACIc1D8AAAAAIhzUPwAAAAAiHNQ/AAAAAOAY1D8AAAAA4BjUPwAAAADgGNQ/AAAAAOAY1D8AAAAA4BjUPwAAAADgGNQ/AAAAAOAY1D8AAAAA4BjUPwAAAAC3DNQ/AAAAALcM1D8AAAAAtwzUPwAAAAC3DNQ/AAAAALcM1D8AAAAAtwzUPwAAAACmt8Q/AAAAAKa3xD8AAAAAprfEPwAAAACaENQ/AAAAAJoQ1D8AAAAAmhDUPwAAAACaENQ/AAAAAJoQ1D8AAAAAmhDUPwAAAACaENQ/AAAAAJoQ1D8AAAAAxBfUPwAAAADEF9Q/AAAAAMQX1D8AAAAAxBfUPwAAAADEF9Q/AAAAABTAtz8AAAAASKa3PwAAAABjA9Q/AAAAAGMD1D8AAAAAYwPUPwAAAABjA9Q/AAAAAGMD1D8AAAAAYwPUPwAAAABjA9Q/AAAAAJA/tz8AAAAAyLe3PwAAAABAXrc/AAAAAMjHxD8AAAAAyMfEPwAAAADIx8Q/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "4", + "4", + "4", + "4" + ], + "x0": " ", + "xaxis": "x3", + "y": { + "bdata": "AAAAAEhhtz8AAAAAJTnUPwAAAAAlOdQ/AAAAACU51D8AAAAAJTnUPwAAAAAlOdQ/AAAAACU51D8AAAAAJTnUPwAAAAAlOdQ/AAAAANHS0z8AAAAA0dLTPwAAAADR0tM/AAAAANHS0z8AAAAA0dLTPwAAAADR0tM/AAAAANHS0z8AAAAAgGe3PwAAAAD17NM/AAAAAPXs0z8AAAAA9ezTPwAAAAD17NM/AAAAAPXs0z8AAAAA9ezTPwAAAAD17NM/AAAAACKGxT8AAAAAIobFPwAAAADsSrc/AAAAAPDotz8AAAAAGRjUPwAAAAAZGNQ/AAAAABkY1D8AAAAAGRjUPwAAAAAZGNQ/AAAAABkY1D8AAAAAGRjUPwAAAAAZGNQ/AAAAALzk0z8AAAAAvOTTPwAAAAC85NM/AAAAALzk0z8AAAAAvOTTPwAAAAC85NM/AAAAALzk0z8AAAAAvOTTPwAAAADI2NM/AAAAAMjY0z8AAAAAyNjTPwAAAADI2NM/AAAAAMjY0z8AAAAAyNjTPwAAAADI2NM/AAAAAMjY0z8AAAAAh+rTPwAAAACH6tM/AAAAAIfq0z8AAAAAh+rTPwAAAACH6tM/AAAAAIfq0z8AAAAAh+rTPwAAAACmccQ/AAAAAKZxxD8AAAAApnHEPwAAAAAUWrc/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Single Run (1x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "2", + "2", + "4", + "4", + "4", + "4", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32" + ], + "x0": " ", + "xaxis": "x4", + "y": { + "bdata": "AAAAACBDtz8AAAAAaD23PwAAAAAkR7c/AAAAAETexD8AAAAARN7EPwAAAABE3sQ/AAAAANxhtz8AAAAAIKC3PwAAAAA8ONQ/AAAAADw41D8AAAAAPDjUPwAAAAA8ONQ/AAAAADw41D8AAAAAPDjUPwAAAAA8ONQ/AAAAAMiRtz8AAAAADRXUPwAAAAANFdQ/AAAAAA0V1D8AAAAADRXUPwAAAAANFdQ/AAAAAA0V1D8AAAAADRXUPwAAAAANFdQ/AAAAAAIR1D8AAAAAAhHUPwAAAAACEdQ/AAAAAAIR1D8AAAAAAhHUPwAAAAACEdQ/AAAAAAIR1D8AAAAA/Jy3PwAAAACrMNQ/AAAAAKsw1D8AAAAAqzDUPwAAAACrMNQ/AAAAAKsw1D8AAAAAqzDUPwAAAACrMNQ/AAAAAKsw1D8AAAAA8fnTPwAAAADx+dM/AAAAAPH50z8AAAAA8fnTPwAAAADx+dM/AAAAAPH50z8AAAAA3DzUPwAAAADcPNQ/AAAAANw81D8AAAAA3DzUPwAAAADcPNQ/AAAAANw81D8AAAAA3DzUPwAAAADcPNQ/AAAAADgA1D8AAAAAOADUPwAAAAA4ANQ/AAAAADgA1D8AAAAAOADUPwAAAAA4ANQ/AAAAADgA1D8AAAAAOADUPwAAAAA867c/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y4" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2" + ], + "x0": " ", + "xaxis": "x2", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y2" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=1024 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "box", + "x": [ + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "2", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "4", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1" + ], + "x0": " ", + "xaxis": "x2", + "y": { + "bdata": "AAAAAGp4xT8AAAAAanjFPwAAAADS79M/AAAAANLv0z8AAAAA0u/TPwAAAADS79M/AAAAANLv0z8AAAAA0u/TPwAAAADS79M/AAAAANLv0z8AAAAAzdfTPwAAAADN19M/AAAAAM3X0z8AAAAAzdfTPwAAAADN19M/AAAAAM3X0z8AAAAAzdfTPwAAAADN19M/AAAAAHnx0z8AAAAAefHTPwAAAAB58dM/AAAAAHnx0z8AAAAAefHTPwAAAAB58dM/AAAAAHnx0z8AAAAAefHTPwAAAACM7NM/AAAAAIzs0z8AAAAAjOzTPwAAAACM7NM/AAAAAIzs0z8AAAAAjOzTPwAAAACM7NM/AAAAAIzs0z8AAAAAggPUPwAAAACCA9Q/AAAAAIID1D8AAAAAggPUPwAAAACCA9Q/AAAAAIID1D8AAAAAggPUPwAAAACCA9Q/AAAAACri0z8AAAAAKuLTPwAAAAAq4tM/AAAAACri0z8AAAAAKuLTPwAAAAAq4tM/AAAAACri0z8AAAAAKuLTPwAAAAAM8dM/AAAAAAzx0z8AAAAADPHTPwAAAAAM8dM/AAAAAAzx0z8AAAAADPHTPwAAAAAM8dM/AAAAAAzx0z8AAAAA+/TTPwAAAAD79NM/AAAAAPv00z8AAAAA+/TTPwAAAAD79NM/AAAAAPv00z8AAAAA+/TTPwAAAAD79NM/AAAAAMjf0z8AAAAAyN/TPwAAAADI39M/AAAAAMjf0z8AAAAAyN/TPwAAAADI39M/AAAAAMjf0z8AAAAAyN/TPwAAAADK4tM/AAAAAMri0z8AAAAAyuLTPwAAAADK4tM/AAAAAMri0z8AAAAAyuLTPwAAAADK4tM/AAAAAMri0z8AAAAASdrTPwAAAABJ2tM/AAAAAEna0z8AAAAASdrTPwAAAABJ2tM/AAAAAEna0z8AAAAASdrTPwAAAABJ2tM/AAAAACLi0z8AAAAAIuLTPwAAAAAi4tM/AAAAACLi0z8AAAAAIuLTPwAAAAAi4tM/AAAAACLi0z8AAAAAIuLTPwAAAAAh9tM/AAAAACH20z8AAAAAIfbTPwAAAAAh9tM/AAAAACH20z8AAAAAIfbTPwAAAAAh9tM/AAAAACH20z8AAAAABvDTPwAAAAAG8NM/AAAAAAbw0z8AAAAABvDTPwAAAAAG8NM/AAAAAAbw0z8AAAAABvDTPwAAAAAG8NM/AAAAAGro0z8AAAAAaujTPwAAAABq6NM/AAAAAGro0z8AAAAAaujTPwAAAABq6NM/AAAAAGro0z8AAAAAaujTPwAAAAD0A9Q/AAAAAPQD1D8AAAAA9APUPwAAAAD0A9Q/AAAAAPQD1D8AAAAA9APUPwAAAAD0A9Q/AAAAAPQD1D8AAAAAYffTPwAAAABh99M/AAAAAGH30z8AAAAAYffTPwAAAABh99M/AAAAAGH30z8AAAAAYffTPwAAAABh99M/AAAAAE730z8AAAAATvfTPwAAAABO99M/AAAAAE730z8AAAAATvfTPwAAAABO99M/AAAAAE730z8AAAAATvfTPwAAAAAA8NM/AAAAAADw0z8AAAAAAPDTPwAAAAAA8NM/AAAAAADw0z8AAAAAAPDTPwAAAAAA8NM/AAAAAADw0z8AAAAAmffTPwAAAACZ99M/AAAAAJn30z8AAAAAmffTPwAAAACZ99M/AAAAAJn30z8AAAAAmffTPwAAAACZ99M/AAAAAAcm1D8AAAAABybUPwAAAAAHJtQ/AAAAAAcm1D8AAAAABybUPwAAAAAHJtQ/AAAAAAcm1D8AAAAABybUPwAAAAAW/tM/AAAAABb+0z8AAAAAFv7TPwAAAAAW/tM/AAAAABb+0z8AAAAAFv7TPwAAAAAW/tM/AAAAABb+0z8AAAAAP/zTPwAAAAA//NM/AAAAAD/80z8AAAAAP/zTPwAAAAA//NM/AAAAAD/80z8AAAAAP/zTPwAAAAA//NM/AAAAALn20z8AAAAAufbTPwAAAAC59tM/AAAAALn20z8AAAAAufbTPwAAAAC59tM/AAAAALn20z8AAAAAufbTPwAAAACY8dM/AAAAAJjx0z8AAAAAmPHTPwAAAACY8dM/AAAAAJjx0z8AAAAAmPHTPwAAAACY8dM/AAAAAJjx0z8AAAAAH/rTPwAAAAAf+tM/AAAAAB/60z8AAAAAH/rTPwAAAAAf+tM/AAAAAB/60z8AAAAAH/rTPwAAAAAf+tM/AAAAAJ8U1D8AAAAAnxTUPwAAAACfFNQ/AAAAAJ8U1D8AAAAAnxTUPwAAAACfFNQ/AAAAAJ8U1D8AAAAAnxTUPwAAAAAt9dM/AAAAAC310z8AAAAALfXTPwAAAAAt9dM/AAAAAC310z8AAAAALfXTPwAAAAAt9dM/AAAAAC310z8AAAAAwQnUPwAAAADBCdQ/AAAAAMEJ1D8AAAAAwQnUPwAAAADBCdQ/AAAAAMEJ1D8AAAAAwQnUPwAAAADBCdQ/AAAAAPT90z8AAAAA9P3TPwAAAAD0/dM/AAAAAPT90z8AAAAA9P3TPwAAAAD0/dM/AAAAAPT90z8AAAAA9P3TPwAAAABq/9M/AAAAAGr/0z8AAAAAav/TPwAAAABq/9M/AAAAAGr/0z8AAAAAav/TPwAAAABq/9M/AAAAAGr/0z8AAAAA5+HTPwAAAADn4dM/AAAAAOfh0z8AAAAA5+HTPwAAAADn4dM/AAAAAOfh0z8AAAAA5+HTPwAAAADn4dM/AAAAAHAN1D8AAAAAcA3UPwAAAABwDdQ/AAAAAHAN1D8AAAAAcA3UPwAAAABwDdQ/AAAAAHAN1D8AAAAAcA3UPwAAAACCBNQ/AAAAAIIE1D8AAAAAggTUPwAAAACCBNQ/AAAAAIIE1D8AAAAAggTUPwAAAACCBNQ/AAAAAIIE1D8AAAAAlerTPwAAAACV6tM/AAAAAJXq0z8AAAAAlerTPwAAAACV6tM/AAAAAJXq0z8AAAAAlerTPwAAAACV6tM/AAAAAC7k0z8AAAAALuTTPwAAAAAu5NM/AAAAAC7k0z8AAAAALuTTPwAAAAAu5NM/AAAAAC7k0z8AAAAALuTTPwAAAABdLdQ/AAAAAF0t1D8AAAAAXS3UPwAAAABdLdQ/AAAAAF0t1D8AAAAAXS3UPwAAAAC569M/AAAAALnr0z8AAAAAuevTPwAAAAC569M/AAAAALnr0z8AAAAAuevTPwAAAAC569M/AAAAALnr0z8AAAAAXS3UPwAAAABdLdQ/AAAAAFjq0z8AAAAAWOrTPwAAAABY6tM/AAAAAFjq0z8AAAAAWOrTPwAAAABY6tM/AAAAAFjq0z8AAAAAWOrTPwAAAAB16dM/AAAAAHXp0z8AAAAAdenTPwAAAAB16dM/AAAAAHXp0z8AAAAAdenTPwAAAADsVbc/AAAAADDgtj8AAAAAJGi3PwAAAAAgE7c/AAAAABwRtz8AAAAAuPK2PwAAAAC07bY/AAAAANirtz8AAAAAIFq3PwAAAADkUrc/AAAAAEBWtz8AAAAAxF+3PwAAAADccLc/AAAAAHgytz8AAAAAJEu3PwAAAABoJrc/AAAAAJSxtz8AAAAAJIW3PwAAAACMmLc/AAAAANCGtz8AAAAAmH23PwAAAADjBNQ/AAAAAOME1D8AAAAA4wTUPwAAAADjBNQ/AAAAAOME1D8AAAAA4wTUPwAAAADjBNQ/AAAAANw9tz8AAAAAchTUPwAAAAByFNQ/AAAAAHIU1D8AAAAAchTUPwAAAAByFNQ/AAAAAHIU1D8AAAAAchTUPwAAAABcQLc/AAAAACTZ0z8AAAAAJNnTPwAAAAAk2dM/AAAAACTZ0z8AAAAAJNnTPwAAAAAk2dM/AAAAACTZ0z8AAAAAqE63PwAAAAAv19M/AAAAAC/X0z8AAAAAL9fTPwAAAAAv19M/AAAAAC/X0z8AAAAAL9fTPwAAAAAv19M/AAAAAKwhtz8AAAAAC/rTPwAAAAAL+tM/AAAAAAv60z8AAAAAC/rTPwAAAAAL+tM/AAAAAAv60z8AAAAAC/rTPwAAAABEj7c/AAAAAKLi0z8AAAAAouLTPwAAAACi4tM/AAAAAKLi0z8AAAAAouLTPwAAAACi4tM/AAAAAKLi0z8AAAAAWEO3PwAAAABF5dM/AAAAAEXl0z8AAAAAReXTPwAAAABF5dM/AAAAAEXl0z8AAAAAReXTPwAAAABF5dM/AAAAAMw/tz8AAAAAsdfTPwAAAACx19M/AAAAALHX0z8AAAAAsdfTPwAAAACx19M/AAAAALHX0z8AAAAAsdfTPwAAAADoWLc/AAAAADfl0z8AAAAAN+XTPwAAAAA35dM/AAAAADfl0z8AAAAAN+XTPwAAAAA35dM/AAAAADfl0z8AAAAAnJG3PwAAAACs49M/AAAAAKzj0z8AAAAArOPTPwAAAACs49M/AAAAAKzj0z8AAAAArOPTPwAAAACs49M/AAAAAEDNtz8AAAAA3NPTPwAAAADc09M/AAAAANzT0z8AAAAA3NPTPwAAAADc09M/AAAAANzT0z8AAAAA3NPTPwAAAADc09M/AAAAAIrt0z8AAAAAiu3TPwAAAACK7dM/AAAAAIrt0z8AAAAAiu3TPwAAAACK7dM/AAAAAIrt0z8AAAAAiu3TPwAAAADK0tM/AAAAAMrS0z8AAAAAytLTPwAAAADK0tM/AAAAAMrS0z8AAAAAytLTPwAAAADK0tM/AAAAAMrS0z8AAAAAhQvUPwAAAACFC9Q/AAAAAIUL1D8AAAAAhQvUPwAAAACFC9Q/AAAAAIUL1D8AAAAAhQvUPwAAAACFC9Q/AAAAAHrM0z8AAAAAeszTPwAAAAB6zNM/AAAAAHrM0z8AAAAAeszTPwAAAAB6zNM/AAAAAHrM0z8AAAAAeszTPwAAAAAM1tM/AAAAAAzW0z8AAAAADNbTPwAAAAAM1tM/AAAAAAzW0z8AAAAADNbTPwAAAAAM1tM/AAAAAAzW0z8AAAAAOgbUPwAAAAA6BtQ/AAAAADoG1D8AAAAAOgbUPwAAAAA6BtQ/AAAAADoG1D8AAAAAOgbUPwAAAAA6BtQ/AAAAAO/i0z8AAAAA7+LTPwAAAADv4tM/AAAAAO/i0z8AAAAA7+LTPwAAAADv4tM/AAAAAO/i0z8AAAAA7+LTPwAAAACn0NM/AAAAAKfQ0z8AAAAAp9DTPwAAAACn0NM/AAAAAKfQ0z8AAAAAp9DTPwAAAACn0NM/AAAAAKfQ0z8AAAAADN7TPwAAAAAM3tM/AAAAAAze0z8AAAAADN7TPwAAAAAM3tM/AAAAAAze0z8AAAAADN7TPwAAAAAM3tM/AAAAAG3q0z8AAAAAberTPwAAAABt6tM/AAAAAG3q0z8AAAAAberTPwAAAABt6tM/AAAAAG3q0z8AAAAAberTPwAAAAA/7dM/AAAAAD/t0z8AAAAAP+3TPwAAAAA/7dM/AAAAAD/t0z8AAAAAP+3TPwAAAAA/7dM/AAAAAD/t0z8AAAAAIO3TPwAAAAAg7dM/AAAAACDt0z8AAAAAIO3TPwAAAAAg7dM/AAAAACDt0z8AAAAAIO3TPwAAAAAg7dM/AAAAAHjr0z8AAAAAeOvTPwAAAAB469M/AAAAAHjr0z8AAAAAeOvTPwAAAAB469M/AAAAAHjr0z8AAAAAeOvTPwAAAADs79M/AAAAAOzv0z8AAAAA7O/TPwAAAADs79M/AAAAAOzv0z8AAAAA7O/TPwAAAADs79M/AAAAAOzv0z8AAAAA7OjTPwAAAADs6NM/AAAAAOzo0z8AAAAA7OjTPwAAAADs6NM/AAAAAOzo0z8AAAAA7OjTPwAAAADs6NM/AAAAABTn0z8AAAAAFOfTPwAAAAAU59M/AAAAABTn0z8AAAAAFOfTPwAAAAAU59M/AAAAABTn0z8AAAAAFOfTPwAAAAAP5dM/AAAAAA/l0z8AAAAAD+XTPwAAAAAP5dM/AAAAAA/l0z8AAAAAD+XTPwAAAAAP5dM/AAAAAA/l0z8AAAAAjPDTPwAAAACM8NM/AAAAAIzw0z8AAAAAjPDTPwAAAACM8NM/AAAAAIzw0z8AAAAAjPDTPwAAAACM8NM/AAAAAOPZ0z8AAAAA49nTPwAAAADj2dM/AAAAAOPZ0z8AAAAA49nTPwAAAADj2dM/AAAAAOPZ0z8AAAAASpXEPwAAAABKlcQ/AAAAAEqVxD8AAAAAcKW3PwAAAAAUicQ/AAAAABSJxD8AAAAAFInEPwAAAABgf7c/AAAAALStxD8AAAAAtK3EPwAAAAC0rcQ/AAAAAKistz8AAAAAdKXEPwAAAAB0pcQ/AAAAAHSlxD8AAAAAbHe3PwAAAAC2ncQ/AAAAALadxD8AAAAAtp3EPwAAAAAMkrc/AAAAALiXxD8AAAAAuJfEPwAAAAC4l8Q/AAAAALyatz8AAAAAmHfEPwAAAACYd8Q/AAAAAJh3xD8AAAAAWFu3PwAAAAAMo8Q/AAAAAAyjxD8AAAAADKPEPwAAAACsprc/AAAAAOC/xD8AAAAA4L/EPwAAAADgv8Q/AAAAADCJtz8AAAAAwI7EPwAAAADAjsQ/AAAAAMCOxD8AAAAAQEu3PwAAAAAoibc/AAAAAAhRtz8AAAAAPAu3PwAAAAAgcbc/AAAAAOxYtz8AAAAAPEy3PwAAAACYdrc/AAAAACg1tz8AAAAA8E+3PwAAAAB0XLc/", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=1024 output tokens", + "x": 0.24, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.74, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "boxmode": "group", + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server TTFT Distribution per Concurrency
Server-side distribution. At medium concurrencies, encrypted may show LOWER server TTFT because TEE de-batching reduces effective batch size seen by the server." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0, + 0.48 + ], + "title": { + "text": "Concurrency" + } + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + } + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ], + "matches": "x", + "showticklabels": false + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.5, + 0.98 + ], + "matches": "x", + "showticklabels": false + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Server TTFT (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Server TTFT (s)" + } + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.box(\n", + " df_box,\n", + " x='concurrency_str',\n", + " y='server_ttft_s',\n", + " color='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'concurrency_str': CONC_STR,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " points='outliers',\n", + " labels={\n", + " 'concurrency_str': 'Concurrency',\n", + " 'server_ttft_s': 'Server TTFT (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label':'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Server TTFT Distribution per Concurrency
'\n", + " 'Server-side distribution. At medium concurrencies, encrypted may show LOWER server TTFT '\n", + " 'because TEE de-batching reduces effective batch size seen by the server.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "cell-scatter-tee", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=1
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": true, + "type": "scattergl", + "x": { + "bdata": "AAAAAIy2tz8AAAAAyF+3PwAAAABQ17Y/AAAAAARutz8AAAAAbDm3PwAAAABgJLc/AAAAAJwptz8AAAAApCm3PwAAAAAsnrc/AAAAAOhntz8=", + "dtype": "f8" + }, + "xaxis": "x", + "y": [ + 752.5067329406738, + 390.55323600769043, + 388.6263370513916, + 391.74652099609375, + 395.83897590637207, + 372.2505569458008, + 398.2682228088379, + 393.0501937866211, + 371.50025367736816, + 392.61651039123535 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=1
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": true, + "type": "scattergl", + "x": { + "bdata": "AAAAAKSZtz8AAAAAPNK3PwAAAAAcVbc/AAAAAKxMtz8AAAAATHu3PwAAAABcX7c/AAAAAHxetz8AAAAA7F+3PwAAAABkRrc/AAAAAIiKtz8=", + "dtype": "f8" + }, + "xaxis": "x", + "y": [ + 1960.768699645996, + 1856.6787242889404, + 1927.347183227539, + 216.27521514892578, + 1912.3916625976562, + 1821.3865756988525, + 610.759973526001, + 1851.5191078186035, + 1927.4487495422363, + 1994.4241046905518 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=2
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAOwntz8AAAAADIq3PwAAAACoVbc/AAAAAODztj8AAAAAVA+3PwAAAAAkA7c/AAAAAEQmtz8AAAAAeBS3PwAAAADISbc/AAAAAOgftz8AAAAAjCa3PwAAAABIJbc/AAAAAAD0tj8AAAAAjN22PwAAAADAzrY/AAAAAPgYtz8AAAAApBq3PwAAAAAsubY/AAAAAOz5tj8AAAAAePq2Pw==", + "dtype": "f8" + }, + "xaxis": "x2", + "y": [ + 792.3781871795654, + 1098.8364219665527, + 444.57197189331055, + 449.07569885253906, + 547.248363494873, + 548.9590167999268, + 543.7257289886475, + 548.8073825836182, + 452.76784896850586, + 449.3563175201416, + 551.2349605560303, + 549.034595489502, + 393.662691116333, + 393.3126926422119, + 560.8730316162109, + 546.5521812438965, + 386.491060256958, + 378.436803817749, + 544.2204475402832, + 552.6502132415771 + ], + "yaxis": "y2" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=2
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAJhvxT8AAAAAmG/FPwAAAAAMU7c/AAAAADxutz8AAAAAxF23PwAAAAAcYLc/AAAAAGBstz8AAAAADHW3PwAAAACserc/AAAAALiptz8AAAAA3EW3PwAAAABcpLc/AAAAALCctz8AAAAAwGO3PwAAAAC8jrc/AAAAADAstz8AAAAA9I23PwAAAABcQbc/AAAAALCBtz8AAAAAtIu3Pw==", + "dtype": "f8" + }, + "xaxis": "x2", + "y": [ + 1933.3717823028564, + 2026.5486240386963, + 1891.4427757263184, + 3723.597526550293, + 3606.40025138855, + 3559.22269821167, + 3618.7729835510254, + 3268.177032470703, + 1570.0016021728516, + 283.7212085723877, + 347.0644950866699, + 356.8298816680908, + 2003.4027099609375, + 1969.8896408081055, + 1958.2490921020508, + 3378.214120864868, + 3111.030340194702, + 3072.6869106292725, + 3294.3849563598633, + 3671.592950820923 + ], + "yaxis": "y2" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=4
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAIgptz8AAAAAOhjFPwAAAAA6GMU/AAAAADoYxT8AAAAANKK3PwAAAADK18Q/AAAAAMrXxD8AAAAAytfEPwAAAAB8m7c/AAAAAPYMxT8AAAAA9gzFPwAAAAD2DMU/AAAAAGSntz8AAAAAmMTEPwAAAACYxMQ/AAAAAJjExD8AAAAAjJ+3PwAAAADosMQ/AAAAAOiwxD8AAAAA6LDEPwAAAACwcrc/AAAAAHqkxD8AAAAAeqTEPwAAAAB6pMQ/AAAAANBftz8AAAAAjLvEPwAAAACMu8Q/AAAAAIy7xD8AAAAAIEW3PwAAAADGj8Q/AAAAAMaPxD8AAAAAxo/EPwAAAACMabc/AAAAACwwtz8AAAAAkJ63PwAAAAAMn7c/AAAAAEhetz8AAAAA6qDFPwAAAADqoMU/AAAAAKydtz8=", + "dtype": "f8" + }, + "xaxis": "x3", + "y": [ + 439.79406356811523, + 718.8088893890381, + 728.6934852600098, + 827.7065753936768, + 568.7577724456787, + 566.0548210144043, + 692.2028064727783, + 576.5461921691895, + 569.3390369415283, + 573.7533569335938, + 574.3815898895264, + 571.3748931884766, + 572.9348659515381, + 578.4201622009277, + 450.59657096862793, + 574.310302734375, + 567.988395690918, + 695.5885887145996, + 573.993444442749, + 691.6060447692871, + 564.5017623901367, + 569.7610378265381, + 563.4090900421143, + 564.8388862609863, + 564.3725395202637, + 451.2369632720947, + 444.93579864501953, + 563.0176067352295, + 565.9756660461426, + 611.4919185638428, + 521.6567516326904, + 693.4375762939453, + 569.6675777435303, + 612.6818656921387, + 449.27406311035156, + 786.613941192627, + 455.0333023071289, + 631.3896179199219, + 860.9662055969238, + 823.0776786804199 + ], + "yaxis": "y3" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=4
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAGKpxD8AAAAAYqnEPwAAAABiqcQ/AAAAAKSnxD8AAAAApKfEPwAAAACkp8Q/AAAAAFxGxT8AAAAAXEbFPwAAAADQ5MQ/AAAAANDkxD8AAAAA0OTEPwAAAAAoT8U/AAAAAChPxT8AAAAAdG3FPwAAAAB0bcU/AAAAAB5PxT8AAAAAHk/FPwAAAADkp8Q/AAAAAOSnxD8AAAAA5KfEPwAAAACWjcQ/AAAAAJaNxD8AAAAAlo3EPwAAAAAITsU/AAAAAAhOxT8AAAAABnDFPwAAAAAGcMU/AAAAAICHxT8AAAAAgIfFPwAAAAC+jMU/AAAAAL6MxT8AAAAAdGW3PwAAAAB8b8U/AAAAAHxvxT8AAAAAWDm3PwAAAAAoNbc/AAAAAMhKtz8AAAAAvDa3PwAAAAAAFrc/AAAAAIxstz8=", + "dtype": "f8" + }, + "xaxis": "x3", + "y": [ + 371.6304302215576, + 1249.5086193084717, + 1659.2469215393066, + 1435.9593391418457, + 1683.7263107299805, + 3056.082010269165, + 1314.5856857299805, + 2940.436363220215, + 2811.6207122802734, + 3109.3194484710693, + 2870.2969551086426, + 2271.921396255493, + 3576.1725902557373, + 4166.359663009644, + 4169.156789779663, + 2295.358657836914, + 4219.533920288086, + 3069.336414337158, + 3344.0024852752686, + 3602.578639984131, + 1462.2726440429688, + 1637.4800205230713, + 2943.007469177246, + 2125.385046005249, + 3499.417304992676, + 4122.002601623535, + 4146.56662940979, + 4264.359951019287, + 4208.346128463745, + 4206.258296966553, + 4185.000896453857, + 2081.3541412353516, + 4246.887922286987, + 4480.626583099365, + 526.1366367340088, + 1767.5580978393555, + 1978.0857563018799, + 224.87401962280273, + 2135.974168777466, + 1927.3669719696045 + ], + "yaxis": "y3" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=8
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAJAotz8AAAAAMT3UPwAAAAAxPdQ/AAAAADE91D8AAAAAMT3UPwAAAAAxPdQ/AAAAADE91D8AAAAAMT3UPwAAAAAEU7c/AAAAAHZMxT8AAAAAdkzFPwAAAABHP9Q/AAAAAEc/1D8AAAAARz/UPwAAAABHP9Q/AAAAAEc/1D8AAAAAoKzEPwAAAACgrMQ/AAAAAKCsxD8AAAAAoKzEPwAAAACq1sQ/AAAAAKrWxD8AAAAAqtbEPwAAAACq1sQ/AAAAAOZ0xT8AAAAA5nTFPwAAAABkYLc/AAAAAMBJtz8AAAAAZF64PwAAAAB+R8U/AAAAAH5HxT8AAAAA4JO3PwAAAAACusU/AAAAAAK6xT8AAAAAXDa3PwAAAAD0QMU/AAAAAPRAxT8AAAAAfGS3PwAAAADwdcU/AAAAAPB1xT8AAAAAwoPFPwAAAADCg8U/AAAAAPBFtz8AAAAAmDq3PwAAAACEM7c/AAAAAJRjtz8AAAAAKL+3PwAAAADo48Q/AAAAAOjjxD8AAAAA6OPEPwAAAADo48Q/AAAAAPxVtz8AAAAA7LXEPwAAAADstcQ/AAAAAOy1xD8AAAAA7LXEPwAAAAAQdrc/AAAAAFCEtz8AAAAA2Ia3PwAAAAAYwMQ/AAAAABjAxD8AAAAAGMDEPwAAAADcWLc/AAAAANSOtz8AAAAAJIe3PwAAAABamMU/AAAAAFqYxT8AAAAAALrEPwAAAAAAusQ/AAAAAAC6xD8AAAAAMIy3PwAAAAAEfMQ/AAAAAAR8xD8AAAAABHzEPwAAAADEJLc/AAAAABjctj8AAAAARHe3PwAAAAB01rc/AAAAAJTDtz8AAAAAmIa3Pw==", + "dtype": "f8" + }, + "xaxis": "x4", + "y": [ + 463.6034965515137, + 896.7270851135254, + 859.5073223114014, + 1011.089563369751, + 1006.1798095703125, + 1034.3871116638184, + 1049.8285293579102, + 1003.6089420318604, + 778.9034843444824, + 411.1602306365967, + 484.9090576171875, + 686.0895156860352, + 922.3344326019287, + 829.2169570922852, + 855.6931018829346, + 867.8903579711914, + 900.6121158599854, + 813.9619827270508, + 415.93337059020996, + 903.8536548614502, + 472.9607105255127, + 569.29612159729, + 584.9018096923828, + 608.323335647583, + 532.0286750793457, + 527.1878242492676, + 855.0386428833008, + 371.7772960662842, + 383.59951972961426, + 661.4072322845459, + 650.7585048675537, + 652.9192924499512, + 650.7582664489746, + 640.8219337463379, + 653.6259651184082, + 648.0767726898193, + 641.230583190918, + 648.2875347137451, + 467.64302253723145, + 650.2149105072021, + 753.4699440002441, + 510.46061515808105, + 528.1639099121094, + 254.10079956054688, + 221.82536125183105, + 431.0190677642822, + 393.9332962036133, + 613.2583618164062, + 745.2964782714844, + 743.0953979492188, + 760.1163387298584, + 571.9177722930908, + 499.24421310424805, + 567.0270919799805, + 698.5845565795898, + 560.3392124176025, + 571.0325241088867, + 587.4655246734619, + 594.9349403381348, + 862.0812892913818, + 463.6731147766113, + 989.1412258148193, + 574.9969482421875, + 621.9680309295654, + 578.1159400939941, + 839.4308090209961, + 698.5785961151123, + 689.8674964904785, + 685.1601600646973, + 446.4864730834961, + 581.1734199523926, + 434.969425201416, + 559.4038963317871, + 577.8465270996094, + 567.0363903045654, + 654.8824310302734, + 425.01354217529297, + 380.79047203063965, + 385.6637477874756, + 384.0010166168213 + ], + "yaxis": "y4" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=8
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAIxkxT8AAAAAjGTFPwAAAAA67sQ/AAAAADruxD8AAAAAOu7EPwAAAAA67sQ/AAAAAARixT8AAAAABGLFPwAAAABgc7c/AAAAAGRgtz8AAAAAlEi3PwAAAAAOvcQ/AAAAAA69xD8AAAAADr3EPwAAAAC4l8Q/AAAAALiXxD8AAAAAuJfEPwAAAADDBtQ/AAAAAMMG1D8AAAAAwwbUPwAAAADDBtQ/AAAAAMMG1D8AAAAAIH63PwAAAAAoSrc/AAAAAOSCtz8AAAAAEPK3PwAAAADE4bc/AAAAACiatz8AAAAAaDu3PwAAAAAwnbc/AAAAAIqUxT8AAAAAipTFPwAAAACU68Q/AAAAAJTrxD8AAAAAlOvEPwAAAACU68Q/AAAAAGqMxD8AAAAAaozEPwAAAABqjMQ/AAAAAPKbxD8AAAAA8pvEPwAAAADym8Q/AAAAAPKbxD8AAAAANEW3PwAAAAAgYrc/AAAAAHR5tz8AAAAAUJvEPwAAAABQm8Q/AAAAAFCbxD8AAAAAVNm3PwAAAADgtcQ/AAAAAOC1xD8AAAAA4LXEPwAAAABkdbc/AAAAAD6wxD8AAAAAPrDEPwAAAAA+sMQ/AAAAAIwwtz8AAAAAcFe3PwAAAADsVLc/AAAAAKhGtz8AAAAA6E+3PwAAAACsCbc/AAAAAMhetz8AAAAAsIC3PwAAAAB8arc/AAAAAJgntz8AAAAAfE+3PwAAAADETrc/AAAAAGh6tz8AAAAAaI+3PwAAAADUbLc/AAAAABRGtz8AAAAAWI23PwAAAADQX7c/AAAAAChFtz8AAAAAuOm3PwAAAADcXLc/AAAAAHxWtz8=", + "dtype": "f8" + }, + "xaxis": "x4", + "y": [ + 358.0460548400879, + 2252.476930618286, + 2522.6378440856934, + 377.0253658294678, + 3836.031198501587, + 1644.8476314544678, + 2192.9399967193604, + 2193.7875747680664, + 2141.225576400757, + 3846.5185165405273, + 1925.4047870635986, + 3647.5441455841064, + 1881.596326828003, + 1886.4576816558838, + 1631.8168640136719, + 466.73107147216797, + 2875.5290508270264, + 1782.8059196472168, + 747.0223903656006, + 1935.9934329986572, + 3222.191572189331, + 3474.984645843506, + 1919.8546409606934, + 3820.842742919922, + 257.62367248535156, + 1921.10013961792, + 2673.7871170043945, + 3512.23087310791, + 3497.6136684417725, + 3670.179605484009, + 3904.2985439300537, + 3230.8292388916016, + 1512.8202438354492, + 3239.6187782287598, + 3289.7119522094727, + 2287.2474193573, + 360.49818992614746, + 2875.499725341797, + 3011.4424228668213, + 1643.9688205718994, + 1852.938175201416, + 2712.7034664154053, + 2729.8905849456787, + 3352.03218460083, + 240.33570289611816, + 1825.5383968353271, + 2163.2776260375977, + 3168.9298152923584, + 3273.016929626465, + 1942.556619644165, + 2147.451400756836, + 2178.8198947906494, + 3326.505661010742, + 1898.8096714019775, + 1532.9530239105225, + 2671.203136444092, + 2881.7384243011475, + 2927.4590015411377, + 215.8339023590088, + 1836.34352684021, + 1793.583869934082, + 1921.6482639312744, + 2636.1870765686035, + 2449.503183364868, + 1810.4965686798096, + 1916.1062240600586, + 2101.231813430786, + 1964.3218517303467, + 3503.568649291992, + 1662.6181602478027, + 222.52178192138672, + 1496.9096183776855, + 1753.0279159545898, + 1923.9227771759033, + 1143.6643600463867, + 1953.420639038086, + 3676.570415496826, + 3376.682996749878, + 3368.781805038452 + ], + "yaxis": "y4" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=16
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAIBFtz8AAAAA6DTUPwAAAADoNNQ/AAAAAOg01D8AAAAA6DTUPwAAAADoNNQ/AAAAAOg01D8AAAAA6DTUPwAAAADoNNQ/AAAAAGgI1D8AAAAAaAjUPwAAAABoCNQ/AAAAAGgI1D8AAAAAaAjUPwAAAABoCNQ/AAAAAGgI1D8AAAAAaAjUPwAAAAAzQ9Q/AAAAADND1D8AAAAAM0PUPwAAAAAzQ9Q/AAAAADND1D8AAAAAM0PUPwAAAAAzQ9Q/AAAAAAIixT8AAAAAM0PUPwAAAAACIsU/AAAAAAIixT8AAAAAAiLFPwAAAADMcrc/AAAAAHhRtz8AAAAAS+/TPwAAAABL79M/AAAAAEvv0z8AAAAAS+/TPwAAAABL79M/AAAAAEvv0z8AAAAAS+/TPwAAAABL79M/AAAAABQ4tz8AAAAA3Da3PwAAAADY6LY/AAAAAMgytz8AAAAAwNi3PwAAAADE07c/AAAAAHg2tz8AAAAArC23PwAAAABw07c/AAAAAFR0tz8AAAAACEK3PwAAAAB+pcU/AAAAAH6lxT8AAAAAeD+3PwAAAAB0hcU/AAAAAHSFxT8AAAAAQE+3PwAAAADUhMU/AAAAANSExT8AAAAAKGi3PwAAAADwb8U/AAAAAPBvxT8AAAAA+Bu4PwAAAABqTcU/AAAAAGpNxT8AAAAAaF+3PwAAAAB2iMU/AAAAAHaIxT8AAAAAVsrEPwAAAABWysQ/AAAAAFbKxD8AAAAAVsrEPwAAAAA0YcU/AAAAADRhxT8AAAAAYrvEPwAAAABiu8Q/AAAAAGK7xD8AAAAAYrvEPwAAAAAYbcU/AAAAABhtxT8AAAAAcqrEPwAAAAByqsQ/AAAAAHKqxD8AAAAANHC3PwAAAACUZMU/AAAAAJRkxT8AAAAAKHW3PwAAAABmZ8U/AAAAAGZnxT8AAAAAoG63PwAAAABKfcU/AAAAAEp9xT8AAAAANCO3PwAAAAAAo7c/AAAAAESBtz8AAAAALq7EPwAAAAAursQ/AAAAAC6uxD8AAAAALq7EPwAAAAD0k8Q/AAAAAPSTxD8AAAAA9JPEPwAAAADOlsQ/AAAAAM6WxD8AAAAAzpbEPwAAAADOlsQ/AAAAAOxctz8AAAAA+m7FPwAAAAD6bsU/AAAAANyRxT8AAAAA3JHFPwAAAABGxcQ/AAAAAEbFxD8AAAAARsXEPwAAAAA4lLc/AAAAACDHtz8AAAAA/GK3PwAAAADUPrc/AAAAAJgptz8AAAAAHijFPwAAAAAeKMU/AAAAADpU1D8AAAAAOlTUPwAAAAA6VNQ/AAAAADpU1D8AAAAAOlTUPwAAAAA6VNQ/AAAAAFyhxD8AAAAAXKHEPwAAAABcocQ/AAAAAIjSxD8AAAAAiNLEPwAAAACI0sQ/AAAAAIjSxD8AAAAAWhLFPwAAAABaEsU/AAAAAFoSxT8AAAAA9JPEPwAAAAD0k8Q/AAAAAPSTxD8AAAAA9JPEPwAAAABUELc/AAAAAABwtz8=", + "dtype": "f8" + }, + "xaxis": "x5", + "y": [ + 535.3376865386963, + 858.565092086792, + 916.2557125091553, + 904.7963619232178, + 850.1498699188232, + 883.2552433013916, + 1034.041166305542, + 1083.4195613861084, + 1031.0816764831543, + 1627.7172565460205, + 1596.9161987304688, + 1590.8620357513428, + 1011.7766857147217, + 1616.7998313903809, + 1612.074375152588, + 1562.7858638763428, + 1700.3982067108154, + 1170.785903930664, + 1146.6758251190186, + 1156.836986541748, + 1010.9138488769531, + 1037.3451709747314, + 1193.518877029419, + 1198.8866329193115, + 675.9753227233887, + 1327.1567821502686, + 804.0604591369629, + 791.3599014282227, + 814.2564296722412, + 432.69872665405273, + 454.94890213012695, + 828.8054466247559, + 833.33420753479, + 801.0070323944092, + 761.9709968566895, + 990.0102615356445, + 968.5893058776855, + 1014.5061016082764, + 1023.2336521148682, + 1075.9294033050537, + 384.11855697631836, + 650.641918182373, + 525.0258445739746, + 394.7277069091797, + 394.6518898010254, + 386.21973991394043, + 381.9887638092041, + 387.2537612915039, + 591.4194583892822, + 431.9872856140137, + 857.7420711517334, + 872.1942901611328, + 658.5719585418701, + 653.4836292266846, + 665.9224033355713, + 661.0896587371826, + 650.3884792327881, + 662.9769802093506, + 658.4053039550781, + 650.489330291748, + 661.0679626464844, + 662.7914905548096, + 655.8640003204346, + 664.3092632293701, + 653.8107395172119, + 646.881103515625, + 664.0698909759521, + 986.7067337036133, + 981.2631607055664, + 699.5694637298584, + 987.2746467590332, + 668.0443286895752, + 681.2543869018555, + 675.7843494415283, + 670.8893775939941, + 669.8493957519531, + 673.2640266418457, + 668.7419414520264, + 677.2193908691406, + 614.6080493927002, + 674.1604804992676, + 665.3494834899902, + 377.1941661834717, + 746.3967800140381, + 745.7506656646729, + 656.4958095550537, + 655.6000709533691, + 649.4503021240234, + 652.4372100830078, + 476.5431880950928, + 648.3745574951172, + 655.8640003204346, + 398.8232612609863, + 289.1533374786377, + 502.69293785095215, + 644.160270690918, + 660.5286598205566, + 647.4952697753906, + 866.8811321258545, + 975.8508205413818, + 608.2146167755127, + 663.9363765716553, + 586.0195159912109, + 579.8611640930176, + 580.4073810577393, + 678.4307956695557, + 532.5961112976074, + 529.5910835266113, + 551.2189865112305, + 535.1076126098633, + 790.3738021850586, + 912.4822616577148, + 925.0080585479736, + 586.026668548584, + 376.79409980773926, + 382.3211193084717, + 386.42048835754395, + 217.46182441711426, + 614.8812770843506, + 611.6111278533936, + 650.7363319396973, + 1057.8269958496094, + 1162.1158123016357, + 1174.9074459075928, + 887.6981735229492, + 806.4923286437988, + 824.4123458862305, + 814.3272399902344, + 424.9601364135742, + 597.0065593719482, + 742.6621913909912, + 606.9180965423584, + 597.4428653717041, + 580.3050994873047, + 601.4323234558105, + 586.829423904419, + 588.5810852050781, + 578.9620876312256, + 571.0654258728027, + 581.7875862121582, + 557.9164028167725, + 427.80447006225586 + ], + "yaxis": "y5" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=16
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAANiUtz8AAAAAAAvUPwAAAAAAC9Q/AAAAAAAL1D8AAAAAAAvUPwAAAAAAC9Q/AAAAAAAL1D8AAAAAAAvUPwAAAAAAC9Q/AAAAAIEP1D8AAAAAgQ/UPwAAAACBD9Q/AAAAAIEP1D8AAAAAgQ/UPwAAAACBD9Q/AAAAAIEP1D8AAAAAgQ/UPwAAAAAJ69M/AAAAAAnr0z8AAAAACevTPwAAAAAJ69M/AAAAAAnr0z8AAAAAsODTPwAAAACw4NM/AAAAALDg0z8AAAAAsODTPwAAAACw4NM/AAAAADivxD8AAAAAOK/EPwAAAAA4r8Q/AAAAACSYtz8AAAAAPqDEPwAAAAA+oMQ/AAAAAD6gxD8AAAAA9GS3PwAAAABe/tM/AAAAAF7+0z8AAAAAXv7TPwAAAABe/tM/AAAAAF7+0z8AAAAAyIPFPwAAAADIg8U/AAAAAKivtz8AAAAAtE63PwAAAADcxrc/AAAAAIA7tz8AAAAATDe3PwAAAAAEILc/AAAAACRCtz8AAAAAMEXFPwAAAAAwRcU/AAAAACwwtz8AAAAA1Dq3PwAAAADYH7c/AAAAACJOxT8AAAAAIk7FPwAAAACUQbc/AAAAABChtz8AAAAA+JG3PwAAAABQebc/AAAAADpwxT8AAAAAOnDFPwAAAAC2fcU/AAAAALZ9xT8AAAAARIm3PwAAAADUZLc/AAAAAC5oxT8AAAAALmjFPwAAAADQQdQ/AAAAANBB1D8AAAAA0EHUPwAAAADQQdQ/AAAAANBB1D8AAAAA0EHUPwAAAACV49M/AAAAAJXj0z8AAAAAlePTPwAAAACV49M/AAAAAJXj0z8AAAAAl+bTPwAAAACX5tM/AAAAAJfm0z8AAAAAl+bTPwAAAACX5tM/AAAAAPni0z8AAAAA+eLTPwAAAAD54tM/AAAAAPni0z8AAAAA+eLTPwAAAAB96dM/AAAAAH3p0z8AAAAAfenTPwAAAAB96dM/AAAAAH3p0z8AAAAAfenTPwAAAAB96dM/AAAAALDFxD8AAAAAsMXEPwAAAACwxcQ/AAAAALDFxD8AAAAAy+bTPwAAAADL5tM/AAAAAMvm0z8AAAAAy+bTPwAAAADL5tM/AAAAAMvm0z8AAAAAilzFPwAAAACKXMU/AAAAAFQSuD8AAAAA5I63PwAAAAC8Q7c/AAAAAORotz8AAAAAjCK3PwAAAADYg7c/AAAAAOAitz8AAAAAqDu3PwAAAABEvLc/AAAAADCrtz8AAAAAdgDUPwAAAAB2ANQ/AAAAAHYA1D8AAAAAdgDUPwAAAAB2ANQ/AAAAAND/0z8AAAAA0P/TPwAAAADQ/9M/AAAAAND/0z8AAAAA0P/TPwAAAABgdLc/AAAAAMBWtz8AAAAA9CK4PwAAAAAMibc/AAAAADiCtz8AAAAAuAfUPwAAAAC4B9Q/AAAAALgH1D8AAAAAuAfUPwAAAAC4B9Q/AAAAAED90z8AAAAAQP3TPwAAAABA/dM/AAAAAED90z8AAAAAQP3TPwAAAAAAerc/AAAAALA5tz8AAAAAfJ23Pw==", + "dtype": "f8" + }, + "xaxis": "x5", + "y": [ + 2146.587371826172, + 2465.3170108795166, + 3608.2406044006348, + 3895.158290863037, + 4023.125648498535, + 3958.4646224975586, + 3987.2939586639404, + 4179.4116497039795, + 4146.444082260132, + 4654.9928188323975, + 4659.415483474731, + 6102.422714233398, + 2260.3890895843506, + 6330.011367797852, + 2552.0052909851074, + 6221.1151123046875, + 6250.928640365601, + 2587.8920555114746, + 2527.0426273345947, + 2634.701728820801, + 3045.1674461364746, + 3471.341371536255, + 473.91676902770996, + 554.3606281280518, + 1280.7722091674805, + 2152.824878692627, + 2110.8522415161133, + 1912.4755859375, + 3050.67777633667, + 3590.712308883667, + 1923.325777053833, + 2069.624662399292, + 3169.6434020996094, + 3360.238790512085, + 1926.3176918029785, + 1580.4705619812012, + 2644.754409790039, + 3699.9082565307617, + 3490.2687072753906, + 3444.180488586426, + 2210.9909057617188, + 1864.3097877502441, + 1926.8267154693604, + 3700.9832859039307, + 1972.6872444152832, + 1968.4839248657227, + 1146.3525295257568, + 1927.5591373443604, + 1159.3434810638428, + 2068.9749717712402, + 2249.2027282714844, + 2119.0896034240723, + 1761.3534927368164, + 1927.7591705322266, + 2283.9343547821045, + 3725.5189418792725, + 1849.3726253509521, + 3360.443592071533, + 1862.40816116333, + 2969.8574542999268, + 2161.393642425537, + 3813.347101211548, + 3158.6198806762695, + 2543.6325073242188, + 2132.0531368255615, + 1707.3407173156738, + 3629.1823387145996, + 3368.8130378723145, + 2462.651491165161, + 1855.6091785430908, + 3087.9249572753906, + 3191.6215419769287, + 3204.474449157715, + 3286.1077785491943, + 3130.7573318481445, + 3720.7770347595215, + 3312.13641166687, + 3760.2202892303467, + 2150.419235229492, + 2824.4423866271973, + 2964.768648147583, + 3992.6633834838867, + 3920.6109046936035, + 4068.4938430786133, + 2382.7483654022217, + 639.9669647216797, + 817.2578811645508, + 2484.880208969116, + 3830.394744873047, + 1812.587022781372, + 2869.446277618408, + 3113.513946533203, + 3297.8949546813965, + 3749.130964279175, + 3873.8253116607666, + 3416.5358543395996, + 1604.3474674224854, + 1177.9570579528809, + 1457.4134349822998, + 3415.647268295288, + 1853.2612323760986, + 1728.8575172424316, + 2728.236675262451, + 3085.77036857605, + 3389.4948959350586, + 3459.3420028686523, + 4145.936965942383, + 4005.826950073242, + 1705.857753753662, + 1974.0045070648193, + 3900.4671573638916, + 220.17431259155273, + 1663.686990737915, + 589.8947715759277, + 226.7017364501953, + 1925.5614280700684, + 1541.041374206543, + 1919.7258949279785, + 2438.9026165008545, + 1020.1895236968994, + 1902.3818969726562, + 2256.6869258880615, + 2448.922872543335, + 1321.901798248291, + 1337.93044090271, + 2839.153528213501, + 3073.8415718078613, + 3848.7207889556885, + 2098.4530448913574, + 1952.0602226257324, + 1819.3178176879883, + 2166.865348815918, + 1981.8181991577148, + 2284.1384410858154, + 658.447265625, + 2457.6869010925293, + 3524.9218940734863, + 3550.2731800079346, + 1836.064100265503, + 2836.359977722168, + 2373.000383377075, + 4031.2247276306152, + 3647.5958824157715, + 3687.962532043457, + 1878.5998821258545, + 225.26288032531738 + ], + "yaxis": "y5" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=32
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "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", + "dtype": "f8" + }, + "xaxis": "x6", + "y": [ + 590.4524326324463, + 687.3855590820312, + 1028.5987854003906, + 1087.4547958374023, + 1192.5914287567139, + 1206.7861557006836, + 1229.3448448181152, + 1182.4114322662354, + 1156.8593978881836, + 1273.1280326843262, + 1601.0425090789795, + 1713.7222290039062, + 1722.0571041107178, + 1674.3290424346924, + 1783.5888862609863, + 1705.1942348480225, + 1667.6087379455566, + 1671.4146137237549, + 2103.9183139801025, + 2260.3955268859863, + 2241.9331073760986, + 2240.546464920044, + 2230.1974296569824, + 2315.47474861145, + 2269.590139389038, + 2305.799722671509, + 2796.6084480285645, + 2683.000326156616, + 430.11975288391113, + 801.2697696685791, + 790.0302410125732, + 782.7942371368408, + 569.2760944366455, + 533.6687564849854, + 529.4530391693115, + 409.47794914245605, + 658.4596633911133, + 844.0907001495361, + 446.2099075317383, + 712.4247550964355, + 696.6648101806641, + 673.7747192382812, + 618.0179119110107, + 855.4306030273438, + 557.5354099273682, + 667.262077331543, + 664.6478176116943, + 678.600549697876, + 674.2465496063232, + 551.0408878326416, + 558.9911937713623, + 804.2283058166504, + 800.9524345397949, + 676.6657829284668, + 669.661283493042, + 685.0306987762451, + 801.2776374816895, + 798.0737686157227, + 681.8301677703857, + 485.8975410461426, + 670.9845066070557, + 673.691987991333, + 668.060302734375, + 668.6656475067139, + 419.01636123657227, + 860.3286743164062, + 856.5304279327393, + 568.2690143585205, + 729.8009395599365, + 726.7177104949951, + 724.0750789642334, + 673.2971668243408, + 667.5796508789062, + 541.1458015441895, + 620.6929683685303, + 805.1416873931885, + 667.5674915313721, + 673.0523109436035, + 669.0194606781006, + 555.9737682342529, + 615.5903339385986, + 797.7855205535889, + 731.3711643218994, + 676.8932342529297, + 674.086332321167, + 764.2757892608643, + 376.28912925720215, + 841.0348892211914, + 919.093132019043, + 901.8394947052002, + 914.090633392334, + 922.0068454742432, + 447.6912021636963, + 828.7444114685059, + 981.6522598266602, + 1004.5511722564697, + 993.4780597686768, + 1020.3032493591309, + 1005.3188800811768, + 427.706241607666, + 231.29010200500488, + 519.2854404449463, + 394.9542045593262, + 447.7241039276123, + 456.2361240386963, + 547.5471019744873, + 925.0349998474121, + 918.9982414245605, + 614.6805286407471, + 800.1606464385986, + 474.64561462402344, + 723.8669395446777, + 717.4921035766602, + 466.9761657714844, + 489.0468120574951, + 590.1169776916504, + 576.7571926116943, + 720.0322151184082, + 592.3378467559814, + 587.641716003418, + 593.1506156921387, + 635.3776454925537, + 592.0579433441162, + 585.1976871490479, + 456.7408561706543, + 589.6263122558594, + 572.981595993042, + 679.724931716919, + 441.68734550476074, + 860.0032329559326, + 548.3534336090088, + 628.3962726593018, + 529.2096138000488, + 387.82429695129395, + 384.8903179168701, + 704.5643329620361, + 699.8746395111084, + 644.7129249572754, + 755.6362152099609, + 553.5807609558105, + 561.4957809448242, + 572.0474720001221, + 565.8516883850098, + 596.3037014007568, + 639.0368938446045, + 659.785270690918, + 549.9465465545654, + 692.9373741149902, + 302.8368949890137, + 662.0237827301025, + 679.0981292724609, + 692.0311450958252, + 806.2961101531982, + 850.2843379974365, + 816.6792392730713, + 1154.7293663024902, + 605.5405139923096, + 675.6596565246582, + 697.2014904022217, + 690.4253959655762, + 686.9511604309082, + 1082.7662944793701, + 1082.3006629943848, + 456.5303325653076, + 675.9905815124512, + 812.3633861541748, + 831.3930034637451, + 811.7263317108154, + 725.8756160736084, + 719.4514274597168, + 830.9526443481445, + 1232.781171798706, + 859.2970371246338, + 872.1358776092529, + 857.8028678894043, + 810.5943202972412, + 420.17626762390137, + 829.3228149414062, + 474.459171295166, + 473.6294746398926, + 556.2095642089844, + 579.5464515686035, + 455.06978034973145, + 461.0459804534912, + 591.1891460418701, + 584.571123123169, + 719.8331356048584, + 598.3924865722656, + 648.5271453857422, + 712.6591205596924, + 591.3991928100586, + 707.7541351318359, + 448.1921195983887, + 713.4358882904053, + 593.5564041137695, + 586.9648456573486, + 462.07547187805176, + 478.62744331359863, + 546.241283416748, + 544.7494983673096, + 757.6632499694824, + 796.576976776123, + 569.756269454956, + 614.0217781066895, + 957.2601318359375, + 996.9758987426758, + 1002.2461414337158, + 1056.6303730010986, + 1134.0086460113525, + 1122.0190525054932, + 1168.6553955078125, + 1154.7656059265137, + 984.1227531433105, + 1013.4952068328857, + 1660.6025695800781, + 607.5160503387451, + 1717.4851894378662, + 910.6955528259277, + 883.9764595031738, + 965.8913612365723, + 432.539701461792, + 695.514440536499, + 818.1459903717041, + 808.02321434021, + 534.618616104126, + 598.1125831604004, + 654.4854640960693, + 580.0960063934326, + 540.6386852264404, + 552.2723197937012, + 857.5122356414795, + 801.3408184051514, + 733.2861423492432, + 1018.5770988464355, + 1042.4103736877441, + 1037.1830463409424, + 883.3122253417969, + 889.230489730835, + 519.3531513214111, + 580.9028148651123, + 561.0852241516113, + 579.0033340454102, + 474.9796390533447, + 284.44528579711914, + 387.7241611480713, + 546.5331077575684, + 424.7596263885498, + 761.5647315979004, + 839.3206596374512, + 818.2811737060547, + 842.3287868499756, + 576.0719776153564, + 434.4041347503662, + 570.9683895111084, + 621.8392848968506, + 577.1465301513672, + 658.1106185913086, + 379.5745372772217 + ], + "yaxis": "y6" + }, + { + "hovertemplate": "Output Tokens=1024 output tokens
Concurrency=32
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "1024 output tokens", + "marker": { + "color": "#EF553B", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "1024 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "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", + "dtype": "f8" + }, + "xaxis": "x6", + "y": [ + 2097.5706577301025, + 2527.4710655212402, + 3683.8972568511963, + 3977.21004486084, + 4142.2529220581055, + 4187.486410140991, + 4098.612546920776, + 4154.852390289307, + 4106.105327606201, + 4546.347856521606, + 4647.386312484741, + 5402.260065078735, + 5665.239334106445, + 5768.322229385376, + 5968.045473098755, + 5936.90824508667, + 6177.299976348877, + 6697.6728439331055, + 7786.321401596069, + 7756.343364715576, + 7760.385513305664, + 7900.44903755188, + 8238.848209381104, + 8353.669166564941, + 8259.726524353027, + 8727.750062942505, + 8819.157838821411, + 9588.932275772095, + 9978.430032730103, + 10205.516576766968, + 10185.131788253784, + 8225.178718566895, + 10294.214963912964, + 8111.31477355957, + 6769.239664077759, + 1901.017665863037, + 3983.4694862365723, + 4062.6659393310547, + 1934.1604709625244, + 1877.648115158081, + 1860.759973526001, + 2421.5824604034424, + 3377.167224884033, + 3995.255947113037, + 3550.2302646636963, + 3536.2942218780518, + 1634.2506408691406, + 3111.6135120391846, + 3288.479804992676, + 364.76945877075195, + 1947.6759433746338, + 754.840612411499, + 1697.0922946929932, + 2440.1917457580566, + 1930.6919574737549, + 1562.241554260254, + 2916.191339492798, + 2601.7842292785645, + 2788.5613441467285, + 1928.6253452301025, + 2952.8937339782715, + 1690.3986930847168, + 2549.781084060669, + 2964.4834995269775, + 2130.6591033935547, + 1857.264757156372, + 1922.1069812774658, + 1924.6680736541748, + 1926.5265464782715, + 1564.4934177398682, + 2128.6838054656982, + 2308.9895248413086, + 1960.6616497039795, + 955.341100692749, + 3100.661039352417, + 2205.031394958496, + 1837.336778640747, + 1212.653636932373, + 2337.034225463867, + 2544.2936420440674, + 2998.3866214752197, + 2732.1372032165527, + 3769.951820373535, + 2895.448684692383, + 2087.324619293213, + 4409.5299243927, + 4718.987226486206, + 3519.1328525543213, + 4897.566318511963, + 4859.668493270874, + 4047.6059913635254, + 4288.596630096436, + 2900.4833698272705, + 2381.887197494507, + 2711.0114097595215, + 3045.069456100464, + 3589.573621749878, + 3960.1423740386963, + 4279.764890670776, + 2331.7363262176514, + 2470.0398445129395, + 3453.367233276367, + 1697.211503982544, + 2002.3691654205322, + 1674.6041774749756, + 2666.900634765625, + 3383.068561553955, + 3725.6312370300293, + 3405.4298400878906, + 3229.112148284912, + 1929.9051761627197, + 673.710823059082, + 3220.4959392547607, + 255.39469718933105, + 1917.4671173095703, + 1760.6143951416016, + 456.1038017272949, + 409.88731384277344, + 2203.8726806640625, + 2469.197988510132, + 3250.4544258117676, + 3734.1232299804688, + 2114.3152713775635, + 3335.2725505828857, + 2626.3115406036377, + 3272.0580101013184, + 3233.4506511688232, + 1868.588924407959, + 2256.253957748413, + 3671.703338623047, + 2634.981632232666, + 3679.6751022338867, + 1926.5899658203125, + 3456.3393592834473, + 214.6933078765869, + 1881.765604019165, + 1123.157262802124, + 1123.6810684204102, + 2413.8946533203125, + 1501.0719299316406, + 2532.2489738464355, + 2954.902172088623, + 1305.1581382751465, + 1774.4297981262207, + 3448.047637939453, + 2328.5703659057617, + 2306.3971996307373, + 2736.0692024230957, + 2704.5247554779053, + 2679.7842979431152, + 3763.498067855835, + 4208.406209945679, + 4185.838222503662, + 4338.377475738525, + 4366.828680038452, + 4799.214839935303, + 4846.453666687012, + 3026.9806385040283, + 3688.6825561523438, + 6136.718273162842, + 3531.7227840423584, + 6495.445489883423, + 6486.7565631866455, + 3194.988489151001, + 4077.1427154541016, + 2826.9011974334717, + 2844.8100090026855, + 2959.4664573669434, + 4007.805347442627, + 4182.333707809448, + 4670.297145843506, + 4793.842315673828, + 5842.503070831299, + 6052.236080169678, + 2272.7508544921875, + 2294.5492267608643, + 4212.2931480407715, + 1970.350980758667, + 1922.5680828094482, + 234.13681983947754, + 1920.0103282928467, + 483.0763339996338, + 1738.07954788208, + 3224.3406772613525, + 1918.3688163757324, + 1767.486572265625, + 1778.8941860198975, + 2576.953649520874, + 2124.2127418518066, + 3846.700429916382, + 2332.9765796661377, + 3667.1578884124756, + 1990.811824798584, + 1662.6098155975342, + 1921.738624572754, + 2471.7016220092773, + 1896.1386680603027, + 3463.4270668029785, + 3684.115409851074, + 1628.3509731292725, + 1880.4888725280762, + 2473.5748767852783, + 2597.454071044922, + 356.1725616455078, + 1123.6417293548584, + 1998.6112117767334, + 2109.074592590332, + 221.66991233825684, + 1992.997169494629, + 1912.2350215911865, + 1944.2288875579834, + 1239.192247390747, + 3078.549385070801, + 3369.166374206543, + 298.4161376953125, + 2184.445858001709, + 1975.9838581085205, + 2681.6787719726562, + 2962.2857570648193, + 3359.853744506836, + 1085.2649211883545, + 1622.0569610595703, + 2980.3316593170166, + 1731.3017845153809, + 2869.8318004608154, + 2677.470922470093, + 1524.9824523925781, + 1796.2336540222168, + 2737.658739089966, + 2792.898654937744, + 2815.9661293029785, + 3878.340482711792, + 4265.476942062378, + 4324.748277664185, + 4382.472515106201, + 4419.305324554443, + 1754.0147304534912, + 4420.853853225708, + 2244.6415424346924, + 2246.138572692871, + 3145.8823680877686, + 1958.8756561279297, + 1917.7746772766113, + 1697.7012157440186, + 3842.9837226867676, + 3863.295793533325, + 3705.3568363189697, + 212.446928024292, + 1921.8928813934326, + 229.19702529907227, + 1917.112112045288, + 743.8681125640869, + 1586.7438316345215, + 1912.388801574707, + 1927.814245223999, + 262.2528076171875, + 2124.6769428253174, + 2053.110361099243, + 1995.7823753356934, + 218.09768676757812, + 1959.4762325286865, + 3773.8234996795654, + 3958.042860031128, + 1961.3471031188965 + ], + "yaxis": "y6" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Concurrency=1", + "x": 0.075, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=2", + "x": 0.24499999999999997, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=4", + "x": 0.415, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=8", + "x": 0.585, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=16", + "x": 0.7549999999999999, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=32", + "x": 0.925, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 420, + "legend": { + "title": { + "text": "Output Tokens" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Per-Request: TEE Network Latency vs Server TTFT — Encrypted Multi Run
Shows how network latency varies independently from server TTFT. A flat horizontal spread would indicate network latency is independent of server load." + }, + "width": 1400, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.15 + ], + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.16999999999999998, + 0.31999999999999995 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.33999999999999997, + 0.49 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.51, + 0.66 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis5": { + "anchor": "y5", + "domain": [ + 0.6799999999999999, + 0.83 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis6": { + "anchor": "y6", + "domain": [ + 0.85, + 1 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "TEE Network Latency (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis5": { + "anchor": "x5", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis6": { + "anchor": "x6", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Per-request: TEE network latency vs server TTFT (encrypted multi run only)\n", + "df_enc_ind = df_individual[\n", + " (df_individual['label'] == 'Encrypted') &\n", + " (df_individual['run_type'] == 'Multi Run (10x)') &\n", + " (~df_individual['is_error']) &\n", + " (df_individual['server_network_latency_ms'].notna())\n", + "].copy()\n", + "\n", + "fig = px.scatter(\n", + " df_enc_ind,\n", + " x='server_ttft_s',\n", + " y='server_network_latency_ms',\n", + " color='out_tokens_label',\n", + " facet_col='concurrency_str',\n", + " opacity=0.55,\n", + " category_orders={'concurrency_str': CONC_STR},\n", + " labels={\n", + " 'server_ttft_s': 'Server TTFT (s)',\n", + " 'server_network_latency_ms': 'TEE Network Latency (ms)',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'concurrency_str': 'Concurrency',\n", + " },\n", + " title=(\n", + " 'Per-Request: TEE Network Latency vs Server TTFT — Encrypted Multi Run
'\n", + " 'Shows how network latency varies independently from server TTFT. '\n", + " 'A flat horizontal spread would indicate network latency is independent of server load.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=420, width=1400, template='plotly_white')\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "id": "cell-summary-hdr", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "### Full Metric Comparison" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "cell-summary-table", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 MetricRun TypeOutput TokensConcurrencyNon-EncryptedEncryptedDelta% Change
108Client E2E p50 (s)Multi Run (10x)10010.3770.504+0.127+33.7%
109Client E2E p50 (s)Multi Run (10x)10020.6340.658+0.024+3.8%
110Client E2E p50 (s)Multi Run (10x)10040.6580.685+0.027+4.1%
111Client E2E p50 (s)Multi Run (10x)10080.8530.838-0.015-1.7%
112Client E2E p50 (s)Multi Run (10x)100161.0730.791-0.282-26.3%
113Client E2E p50 (s)Multi Run (10x)100322.1650.918-1.247-57.6%
114Client E2E p50 (s)Multi Run (10x)102411.8312.038+0.206+11.3%
115Client E2E p50 (s)Multi Run (10x)102423.6062.692-0.914-25.3%
116Client E2E p50 (s)Multi Run (10x)102442.8863.243+0.357+12.4%
117Client E2E p50 (s)Multi Run (10x)102483.2743.982+0.709+21.6%
118Client E2E p50 (s)Multi Run (10x)1024162.9634.137+1.174+39.6%
119Client E2E p50 (s)Multi Run (10x)1024325.9574.933-1.024-17.2%
96Client E2E p50 (s)Single Run (1x)10010.6121.169+0.558+91.2%
97Client E2E p50 (s)Single Run (1x)10020.5360.932+0.396+73.8%
98Client E2E p50 (s)Single Run (1x)10040.8600.843-0.017-2.0%
99Client E2E p50 (s)Single Run (1x)10081.0151.088+0.073+7.1%
100Client E2E p50 (s)Single Run (1x)100161.1171.173+0.056+5.0%
101Client E2E p50 (s)Single Run (1x)100322.2631.918-0.345-15.2%
102Client E2E p50 (s)Single Run (1x)102411.8290.355-1.474-80.6%
103Client E2E p50 (s)Single Run (1x)102422.1241.987-0.137-6.5%
104Client E2E p50 (s)Single Run (1x)102441.2042.556+1.352+112.3%
105Client E2E p50 (s)Single Run (1x)102483.3793.462+0.083+2.5%
106Client E2E p50 (s)Single Run (1x)1024163.6184.532+0.914+25.2%
107Client E2E p50 (s)Single Run (1x)1024325.0436.671+1.628+32.3%
84Client TTFT p50 (s)Multi Run (10x)10010.2180.335+0.117+53.5%
85Client TTFT p50 (s)Multi Run (10x)10020.4740.492+0.018+3.7%
86Client TTFT p50 (s)Multi Run (10x)10040.5270.559+0.032+6.0%
87Client TTFT p50 (s)Multi Run (10x)10080.6890.699+0.011+1.6%
88Client TTFT p50 (s)Multi Run (10x)100160.9100.672-0.238-26.1%
89Client TTFT p50 (s)Multi Run (10x)100322.0010.799-1.202-60.1%
90Client TTFT p50 (s)Multi Run (10x)102410.1830.326+0.143+78.3%
91Client TTFT p50 (s)Multi Run (10x)102421.9601.729-0.230-11.7%
92Client TTFT p50 (s)Multi Run (10x)102442.0062.103+0.097+4.8%
93Client TTFT p50 (s)Multi Run (10x)102482.1542.674+0.519+24.1%
94Client TTFT p50 (s)Multi Run (10x)1024161.8472.697+0.851+46.1%
95Client TTFT p50 (s)Multi Run (10x)1024324.8384.000-0.838-17.3%
72Client TTFT p50 (s)Single Run (1x)10010.4511.169+0.718+159.1%
73Client TTFT p50 (s)Single Run (1x)10020.3770.765+0.388+102.8%
74Client TTFT p50 (s)Single Run (1x)10040.7330.780+0.047+6.5%
75Client TTFT p50 (s)Single Run (1x)10080.8540.959+0.104+12.2%
76Client TTFT p50 (s)Single Run (1x)100160.9571.016+0.059+6.1%
77Client TTFT p50 (s)Single Run (1x)100322.0981.752-0.346-16.5%
78Client TTFT p50 (s)Single Run (1x)102410.1820.355+0.173+95.0%
79Client TTFT p50 (s)Single Run (1x)102420.2911.163+0.872+299.1%
80Client TTFT p50 (s)Single Run (1x)102440.3280.683+0.355+108.2%
81Client TTFT p50 (s)Single Run (1x)102482.2652.730+0.464+20.5%
82Client TTFT p50 (s)Single Run (1x)1024162.5032.833+0.330+13.2%
83Client TTFT p50 (s)Single Run (1x)1024323.9265.016+1.091+27.8%
132Client Tok/s p50Multi Run (10x)1001629.685590.152-39.533-6.3%
133Client Tok/s p50Multi Run (10x)1002628.471592.733-35.738-5.7%
134Client Tok/s p50Multi Run (10x)1004777.635593.165-184.469-23.7%
135Client Tok/s p50Multi Run (10x)1008612.022593.329-18.693-3.1%
136Client Tok/s p50Multi Run (10x)10016612.372594.182-18.190-3.0%
137Client Tok/s p50Multi Run (10x)10032611.674608.532-3.142-0.5%
138Client Tok/s p50Multi Run (10x)10241621.394584.694-36.700-5.9%
139Client Tok/s p50Multi Run (10x)10242621.498585.532-35.966-5.8%
140Client Tok/s p50Multi Run (10x)10244785.076584.811-200.265-25.5%
141Client Tok/s p50Multi Run (10x)10248616.396588.443-27.954-4.5%
142Client Tok/s p50Multi Run (10x)102416616.397588.818-27.579-4.5%
143Client Tok/s p50Multi Run (10x)102432615.732591.864-23.869-3.9%
120Client Tok/s p50Single Run (1x)1001624.004
121Client Tok/s p50Single Run (1x)1002628.968597.872-31.096-4.9%
122Client Tok/s p50Single Run (1x)1004782.864786.389+3.524+0.5%
123Client Tok/s p50Single Run (1x)1008623.630594.143-29.487-4.7%
124Client Tok/s p50Single Run (1x)10016611.377622.960+11.583+1.9%
125Client Tok/s p50Single Run (1x)10032618.338604.707-13.631-2.2%
126Client Tok/s p50Single Run (1x)10241621.915
127Client Tok/s p50Single Run (1x)10242558.812551.040-7.772-1.4%
128Client Tok/s p50Single Run (1x)10244784.519528.549-255.971-32.6%
129Client Tok/s p50Single Run (1x)10248616.223583.179-33.044-5.4%
130Client Tok/s p50Single Run (1x)102416615.858594.350-21.508-3.5%
131Client Tok/s p50Single Run (1x)102432616.906593.955-22.952-3.7%
204Error Rate (%)Multi Run (10x)10010.0000.000+0.000
205Error Rate (%)Multi Run (10x)10020.0000.000+0.000
206Error Rate (%)Multi Run (10x)10040.0000.000+0.000
207Error Rate (%)Multi Run (10x)10080.0000.000+0.000
208Error Rate (%)Multi Run (10x)100160.00011.250+11.250
209Error Rate (%)Multi Run (10x)100320.00019.375+19.375
210Error Rate (%)Multi Run (10x)102410.0000.000+0.000
211Error Rate (%)Multi Run (10x)102420.0000.000+0.000
212Error Rate (%)Multi Run (10x)102440.0000.000+0.000
213Error Rate (%)Multi Run (10x)102480.0001.250+1.250
214Error Rate (%)Multi Run (10x)1024160.0008.750+8.750
215Error Rate (%)Multi Run (10x)1024320.00017.500+17.500
192Error Rate (%)Single Run (1x)10010.0000.000+0.000
193Error Rate (%)Single Run (1x)10020.0000.000+0.000
194Error Rate (%)Single Run (1x)10040.0000.000+0.000
195Error Rate (%)Single Run (1x)10080.0000.000+0.000
196Error Rate (%)Single Run (1x)100160.0000.000+0.000
197Error Rate (%)Single Run (1x)100320.0000.000+0.000
198Error Rate (%)Single Run (1x)102410.0000.000+0.000
199Error Rate (%)Single Run (1x)102420.0000.000+0.000
200Error Rate (%)Single Run (1x)102440.0000.000+0.000
201Error Rate (%)Single Run (1x)102480.0000.000+0.000
202Error Rate (%)Single Run (1x)1024160.0000.000+0.000
203Error Rate (%)Single Run (1x)1024320.0000.000+0.000
180Req / minMulti Run (10x)1001153.054109.881-43.173-28.2%
181Req / minMulti Run (10x)1002186.242179.823-6.419-3.4%
182Req / minMulti Run (10x)1004357.74431.636-326.108-91.2%
183Req / minMulti Run (10x)1008549.81736.342-513.474-93.4%
184Req / minMulti Run (10x)10016839.31329.502-809.811-96.5%
185Req / minMulti Run (10x)10032848.29928.436-819.864-96.6%
186Req / minMulti Run (10x)1024132.57434.113+1.539+4.7%
187Req / minMulti Run (10x)1024237.78144.928+7.146+18.9%
188Req / minMulti Run (10x)1024482.55546.973-35.583-43.1%
189Req / minMulti Run (10x)10248144.65730.085-114.572-79.2%
190Req / minMulti Run (10x)102416299.23728.748-270.489-90.4%
191Req / minMulti Run (10x)102432309.42330.504-278.919-90.1%
168Req / minSingle Run (1x)100197.33051.228-46.102-47.4%
169Req / minSingle Run (1x)1002171.519109.210-62.310-36.3%
170Req / minSingle Run (1x)1004275.731262.001-13.730-5.0%
171Req / minSingle Run (1x)1008463.535423.746-39.789-8.6%
172Req / minSingle Run (1x)10016570.178546.859-23.319-4.1%
173Req / minSingle Run (1x)10032596.145627.558+31.413+5.3%
174Req / minSingle Run (1x)1024132.659168.327+135.668+415.4%
175Req / minSingle Run (1x)1024256.10555.153-0.952-1.7%
176Req / minSingle Run (1x)1024479.89652.826-27.070-33.9%
177Req / minSingle Run (1x)10248140.031110.432-29.599-21.1%
178Req / minSingle Run (1x)102416186.128147.481-38.647-20.8%
179Req / minSingle Run (1x)102432237.265175.776-61.489-25.9%
60Server E2E p50 (s)Multi Run (10x)10010.2510.260+0.010+3.8%
61Server E2E p50 (s)Multi Run (10x)10020.2510.259+0.008+3.2%
62Server E2E p50 (s)Multi Run (10x)10040.2880.262-0.027-9.2%
63Server E2E p50 (s)Multi Run (10x)10080.4740.291-0.183-38.6%
64Server E2E p50 (s)Multi Run (10x)100160.4740.294-0.181-38.1%
65Server E2E p50 (s)Multi Run (10x)100320.4750.293-0.182-38.4%
66Server E2E p50 (s)Multi Run (10x)102411.7401.807+0.067+3.9%
67Server E2E p50 (s)Multi Run (10x)102421.7401.785+0.046+2.6%
68Server E2E p50 (s)Multi Run (10x)102441.0371.550+0.513+49.5%
69Server E2E p50 (s)Multi Run (10x)102481.4291.490+0.062+4.3%
70Server E2E p50 (s)Multi Run (10x)1024161.4291.751+0.322+22.5%
71Server E2E p50 (s)Multi Run (10x)1024321.4281.622+0.194+13.6%
48Server E2E p50 (s)Single Run (1x)10010.2510.094-0.158-62.6%
49Server E2E p50 (s)Single Run (1x)10020.2510.261+0.011+4.3%
50Server E2E p50 (s)Single Run (1x)10040.2900.276-0.014-4.9%
51Server E2E p50 (s)Single Run (1x)10080.4780.446-0.032-6.8%
52Server E2E p50 (s)Single Run (1x)100160.4760.398-0.079-16.5%
53Server E2E p50 (s)Single Run (1x)100320.4770.481+0.003+0.6%
54Server E2E p50 (s)Single Run (1x)102411.7380.093-1.646-94.7%
55Server E2E p50 (s)Single Run (1x)102422.0010.916-1.085-54.2%
56Server E2E p50 (s)Single Run (1x)102441.0361.913+0.877+84.7%
57Server E2E p50 (s)Single Run (1x)102481.4271.752+0.325+22.8%
58Server E2E p50 (s)Single Run (1x)1024161.4321.882+0.450+31.4%
59Server E2E p50 (s)Single Run (1x)1024321.4281.769+0.341+23.9%
12Server TTFT p50 (s)Multi Run (10x)10010.0910.091-0.000-0.1%
13Server TTFT p50 (s)Multi Run (10x)10020.0910.090-0.001-1.1%
14Server TTFT p50 (s)Multi Run (10x)10040.1610.162+0.001+0.4%
15Server TTFT p50 (s)Multi Run (10x)10080.3110.162-0.149-47.9%
16Server TTFT p50 (s)Multi Run (10x)100160.3110.165-0.146-47.1%
17Server TTFT p50 (s)Multi Run (10x)100320.3120.164-0.148-47.5%
18Server TTFT p50 (s)Multi Run (10x)102410.0920.091-0.001-0.5%
19Server TTFT p50 (s)Multi Run (10x)102420.0920.092-0.000-0.4%
20Server TTFT p50 (s)Multi Run (10x)102440.1610.163+0.003+1.6%
21Server TTFT p50 (s)Multi Run (10x)102480.3120.161-0.151-48.5%
22Server TTFT p50 (s)Multi Run (10x)1024160.3110.311-0.001-0.2%
23Server TTFT p50 (s)Multi Run (10x)1024320.3110.167-0.144-46.4%
0Server TTFT p50 (s)Single Run (1x)10010.0910.093+0.001+1.6%
1Server TTFT p50 (s)Single Run (1x)10020.0910.092+0.001+1.0%
2Server TTFT p50 (s)Single Run (1x)10040.1630.162-0.001-0.4%
3Server TTFT p50 (s)Single Run (1x)10080.3160.313-0.003-1.0%
4Server TTFT p50 (s)Single Run (1x)100160.3140.314-0.000-0.1%
5Server TTFT p50 (s)Single Run (1x)100320.3140.314-0.000-0.1%
6Server TTFT p50 (s)Single Run (1x)102410.0910.092+0.001+0.8%
7Server TTFT p50 (s)Single Run (1x)102420.1680.091-0.077-45.8%
8Server TTFT p50 (s)Single Run (1x)102440.1600.131-0.029-18.0%
9Server TTFT p50 (s)Single Run (1x)102480.3110.314+0.003+1.0%
10Server TTFT p50 (s)Single Run (1x)1024160.3130.314+0.001+0.2%
11Server TTFT p50 (s)Single Run (1x)1024320.3110.314+0.004+1.1%
36Server Tok/s p50Multi Run (10x)1001619.416584.803-34.614-5.6%
37Server Tok/s p50Multi Run (10x)1002619.315584.746-34.568-5.6%
38Server Tok/s p50Multi Run (10x)1004776.275585.039-191.236-24.6%
39Server Tok/s p50Multi Run (10x)1008607.891584.452-23.439-3.9%
40Server Tok/s p50Multi Run (10x)10016605.648584.301-21.348-3.5%
41Server Tok/s p50Multi Run (10x)10032605.877593.517-12.360-2.0%
42Server Tok/s p50Multi Run (10x)10241620.923585.042-35.880-5.8%
43Server Tok/s p50Multi Run (10x)10242620.731585.130-35.601-5.7%
44Server Tok/s p50Multi Run (10x)10244784.177538.217-245.960-31.4%
45Server Tok/s p50Multi Run (10x)10248615.332585.288-30.045-4.9%
46Server Tok/s p50Multi Run (10x)102416614.865587.584-27.281-4.4%
47Server Tok/s p50Multi Run (10x)102432614.868589.279-25.588-4.2%
24Server Tok/s p50Single Run (1x)1001618.574
25Server Tok/s p50Single Run (1x)1002619.233583.614-35.619-5.8%
26Server Tok/s p50Single Run (1x)1004776.964765.256-11.709-1.5%
27Server Tok/s p50Single Run (1x)1008609.028588.329-20.699-3.4%
28Server Tok/s p50Single Run (1x)10016608.304595.598-12.706-2.1%
29Server Tok/s p50Single Run (1x)10032605.646594.129-11.517-1.9%
30Server Tok/s p50Single Run (1x)10241620.919
31Server Tok/s p50Single Run (1x)10242558.313545.003-13.310-2.4%
32Server Tok/s p50Single Run (1x)10244783.937527.983-255.954-32.6%
33Server Tok/s p50Single Run (1x)10248615.830581.324-34.506-5.6%
34Server Tok/s p50Single Run (1x)102416615.436593.467-21.970-3.6%
35Server Tok/s p50Single Run (1x)102432615.421593.045-22.376-3.6%
156Total Throughput (tok/s)Multi Run (10x)1001255.090183.135-71.955-28.2%
157Total Throughput (tok/s)Multi Run (10x)1002310.403246.657-63.746-20.5%
158Total Throughput (tok/s)Multi Run (10x)1004596.24037.515-558.725-93.7%
159Total Throughput (tok/s)Multi Run (10x)1008916.36150.652-865.709-94.5%
160Total Throughput (tok/s)Multi Run (10x)100161398.85542.681-1356.174-96.9%
161Total Throughput (tok/s)Multi Run (10x)100321413.83236.474-1377.359-97.4%
162Total Throughput (tok/s)Multi Run (10x)10241555.924470.868-85.056-15.3%
163Total Throughput (tok/s)Multi Run (10x)10242644.798536.361-108.437-16.8%
164Total Throughput (tok/s)Multi Run (10x)102441062.210618.492-443.718-41.8%
165Total Throughput (tok/s)Multi Run (10x)102481759.995366.618-1393.377-79.2%
166Total Throughput (tok/s)Multi Run (10x)1024163441.721324.169-3117.552-90.6%
167Total Throughput (tok/s)Multi Run (10x)1024323553.464356.617-3196.847-90.0%
144Total Throughput (tok/s)Single Run (1x)1001162.2160.000-162.216-100.0%
145Total Throughput (tok/s)Single Run (1x)1002285.866182.016-103.850-36.3%
146Total Throughput (tok/s)Single Run (1x)1004459.552327.501-132.051-28.7%
147Total Throughput (tok/s)Single Run (1x)1008772.559456.410-316.149-40.9%
148Total Throughput (tok/s)Single Run (1x)10016950.296626.609-323.687-34.1%
149Total Throughput (tok/s)Single Run (1x)10032993.576891.982-101.593-10.2%
150Total Throughput (tok/s)Single Run (1x)10241557.3810.000-557.381-100.0%
151Total Throughput (tok/s)Single Run (1x)10242957.525441.227-516.298-53.9%
152Total Throughput (tok/s)Single Run (1x)102441027.992666.924-361.068-35.1%
153Total Throughput (tok/s)Single Run (1x)102481703.7101250.645-453.065-26.6%
154Total Throughput (tok/s)Single Run (1x)1024162199.4101782.985-416.425-18.9%
155Total Throughput (tok/s)Single Run (1x)1024322762.1562164.786-597.370-21.6%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "ALL_METRICS = [\n", + " ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n", + " ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n", + " ('server_end_to_end_latency_s_p50', 'Server E2E p50 (s)'),\n", + " ('client_ttft_s_p50', 'Client TTFT p50 (s)'),\n", + " ('client_end_to_end_latency_s_p50', 'Client E2E p50 (s)'),\n", + " ('client_output_token_per_s_p50', 'Client Tok/s p50'),\n", + " ('client_total_output_throughput', 'Total Throughput (tok/s)'),\n", + " ('num_completed_requests_per_min', 'Req / min'),\n", + " ('error_rate_pct', 'Error Rate (%)'),\n", + "]\n", + "\n", + "df_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\n", + "df_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n", + "\n", + "rows = []\n", + "for col, label in ALL_METRICS:\n", + " if col not in df_enc_s.columns:\n", + " continue\n", + " for idx in df_enc_s.index:\n", + " if idx not in df_plain_s.index:\n", + " continue\n", + " enc_v = df_enc_s.loc[idx, col]\n", + " plain_v = df_plain_s.loc[idx, col]\n", + " if pd.isna(enc_v) and pd.isna(plain_v):\n", + " continue\n", + " delta = enc_v - plain_v if pd.notna(enc_v) and pd.notna(plain_v) else np.nan\n", + " pct_chg = delta / plain_v * 100 if pd.notna(delta) and plain_v != 0 else np.nan\n", + " rows.append({\n", + " 'Metric': label,\n", + " 'Run Type': idx[0],\n", + " 'Output Tokens': idx[1],\n", + " 'Concurrency': idx[2],\n", + " 'Non-Encrypted': plain_v,\n", + " 'Encrypted': enc_v,\n", + " 'Delta': delta,\n", + " '% Change': pct_chg,\n", + " })\n", + "\n", + "df_summary = pd.DataFrame(rows).sort_values(\n", + " ['Metric', 'Run Type', 'Output Tokens', 'Concurrency']\n", + ")\n", + "\n", + "def _pct_color(val):\n", + " if pd.isna(val): return ''\n", + " if val > 100: return 'background-color: #ff6666'\n", + " if val > 50: return 'background-color: #ffaaaa'\n", + " if val > 20: return 'background-color: #ffd8aa'\n", + " if val > 0: return 'background-color: #fffacc'\n", + " if val < -20: return 'background-color: #aaffaa'\n", + " return ''\n", + "\n", + "df_summary.style \\\n", + " .applymap(_pct_color, subset=['% Change']) \\\n", + " .format({\n", + " 'Non-Encrypted': '{:.3f}',\n", + " 'Encrypted': '{:.3f}',\n", + " 'Delta': '{:+.3f}',\n", + " '% Change': '{:+.1f}%',\n", + " }, na_rep='—')" + ] + }, + { + "cell_type": "markdown", + "id": "cell-tee-overhead-hdr", + "metadata": {}, + "source": [ + "### TEE Overhead Attribution per Scenario" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "cell-tee-overhead-table", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 Run TypeOutput TokensConcurrencyPlain TTFT (s)Enc TTFT (s)Delta (s)Encryption (s)Decryption (s)Network Hop (s)TEE Total (s)TEE % of Enc TTFTNetwork %Encrypt %Decrypt %
0Single Run (1x)10010.45131.16920.71790.00460.00011.06021.064991.07955090.6736490.3975370.008365
1Single Run (1x)10020.37720.76490.38770.00540.00080.82310.8294108.430658107.6111390.7121060.107413
2Single Run (1x)10040.73260.78000.04740.00430.00050.67260.677386.83739786.2309360.5458210.060641
3Single Run (1x)10080.85430.95870.10440.00390.00040.88670.891092.93817792.4866170.4083650.043194
4Single Run (1x)100160.95711.01570.05860.00390.00031.06181.0660104.955459104.5339080.3874770.034075
5Single Run (1x)100322.09841.7525-0.34590.00390.00041.85711.8614106.211863105.9705850.2212610.020017
6Single Run (1x)102410.18200.35490.17290.00490.00010.25170.256772.32637470.9268811.3764440.023049
7Single Run (1x)102420.29141.16300.87160.00450.00341.86821.8761161.314832160.6382720.3857950.290765
8Single Run (1x)102440.32810.68310.35500.00430.00432.39572.4043351.971644350.7104960.6259550.635193
9Single Run (1x)102482.26552.72990.46440.00420.00313.23193.2392118.655980118.3893660.1527930.113821
10Single Run (1x)1024162.50312.83290.32980.00400.00304.41894.4258156.230086155.9859760.1399380.104172
11Single Run (1x)1024323.92575.01631.09060.00390.00296.59986.6067131.704180131.5679330.0782290.058019
12Multi Run (10x)10010.21820.33490.11670.00980.00370.42470.4382130.842490126.8127202.9180651.111705
13Multi Run (10x)10020.47430.49180.01750.00880.00190.53660.5473111.287556109.1113871.7882680.387902
14Multi Run (10x)10040.52750.55930.03180.00790.00110.59950.6085108.803576107.1884141.4143570.200805
15Multi Run (10x)10080.68860.69930.01070.00700.00110.63840.646592.44770591.2911341.0039610.152610
16Multi Run (10x)100160.91040.6725-0.23790.00520.00080.75610.7621113.326543112.4370410.7755090.113993
17Multi Run (10x)100322.00090.7989-1.20200.00550.00070.80320.8094101.318313100.5438600.6860060.088447
18Multi Run (10x)102410.18310.32640.14330.00910.01091.60791.6279498.737439492.6164222.7876843.333333
19Multi Run (10x)102421.95951.7294-0.23010.00910.00762.43222.4490141.608199140.6401120.5287090.439378
20Multi Run (10x)102442.00602.10310.09710.00940.00712.73462.7512130.815658130.0292380.4481190.338301
21Multi Run (10x)102482.15432.67370.51940.00890.00642.26622.281485.32840384.7570970.3311850.240120
22Multi Run (10x)1024161.84672.69730.85060.00810.00522.67912.692499.81681799.3262110.2994110.191195
23Multi Run (10x)1024324.83814.0002-0.83790.00590.00523.14913.160279.00075778.7228040.1483080.129646
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "df_tee_oh = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "df_tee_oh = df_tee_oh.merge(\n", + " df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n", + " columns={'client_ttft_s_p50': 'client_ttft_plain'}\n", + " ),\n", + " on=DIMS,\n", + ")\n", + "\n", + "df_tee_oh['enc_time_s'] = df_tee_oh['total_encryption_time_ms_mean'] / 1000\n", + "df_tee_oh['dec_time_s'] = df_tee_oh['total_decryption_time_ms_mean'] / 1000\n", + "df_tee_oh['network_s'] = df_tee_oh['server_network_latency_ms_mean'] / 1000\n", + "df_tee_oh['tee_total_s'] = df_tee_oh['enc_time_s'] + df_tee_oh['dec_time_s'] + df_tee_oh['network_s']\n", + "df_tee_oh['ttft_delta_s'] = df_tee_oh['client_ttft_s_p50'] - df_tee_oh['client_ttft_plain']\n", + "df_tee_oh['network_pct'] = df_tee_oh['network_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['enc_pct'] = df_tee_oh['enc_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['dec_pct'] = df_tee_oh['dec_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['tee_total_pct'] = df_tee_oh['tee_total_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "\n", + "DISPLAY = {\n", + " 'run_type': 'Run Type',\n", + " 'num_output_tokens': 'Output Tokens',\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'client_ttft_plain': 'Plain TTFT (s)',\n", + " 'client_ttft_s_p50': 'Enc TTFT (s)',\n", + " 'ttft_delta_s': 'Delta (s)',\n", + " 'enc_time_s': 'Encryption (s)',\n", + " 'dec_time_s': 'Decryption (s)',\n", + " 'network_s': 'Network Hop (s)',\n", + " 'tee_total_s': 'TEE Total (s)',\n", + " 'tee_total_pct': 'TEE % of Enc TTFT',\n", + " 'network_pct': 'Network %',\n", + " 'enc_pct': 'Encrypt %',\n", + " 'dec_pct': 'Decrypt %',\n", + "}\n", + "\n", + "df_tee_display = (\n", + " df_tee_oh[list(DISPLAY.keys())]\n", + " .rename(columns=DISPLAY)\n", + " .sort_values(['Run Type', 'Output Tokens', 'Concurrency'])\n", + ")\n", + "\n", + "pct_cols = [c for c in df_tee_display.columns if '%' in c]\n", + "s_cols = [c for c in df_tee_display.columns if '(s)' in c]\n", + "\n", + "df_tee_display.style \\\n", + " .background_gradient(subset=['TEE % of Enc TTFT'], cmap='YlOrRd') \\\n", + " .format({c: '{:.1f}%' for c in pct_cols}) \\\n", + " .format({c: '{:.4f}' for c in s_cols}, na_rep='—')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56a895dd", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7cf9ba4", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From ec9a0d37d6bee5ba6eebd42bcee336ef2b54e818 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Thu, 7 May 2026 17:26:24 -0500 Subject: [PATCH 14/17] model configs for complete runs --- ...akrypto-complete-encrypted-model_configs.csv | 17 +++++++++++++++++ ...pto-complete-non_encrypted-model_configs.csv | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 benchmarking/benchmarking_bundles/datakrypto-complete-encrypted-model_configs.csv create mode 100644 benchmarking/benchmarking_bundles/datakrypto-complete-non_encrypted-model_configs.csv diff --git a/benchmarking/benchmarking_bundles/datakrypto-complete-encrypted-model_configs.csv b/benchmarking/benchmarking_bundles/datakrypto-complete-encrypted-model_configs.csv new file mode 100644 index 000000000..10befcddf --- /dev/null +++ b/benchmarking/benchmarking_bundles/datakrypto-complete-encrypted-model_configs.csv @@ -0,0 +1,17 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,30,3,,, +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,50,5,,, +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,3900,100,320,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,30,3,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,50,5,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,80,8,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,160,16,,, +Llama-xLAM-2-8b-fc-r-encrypted,8000,100,320,32,,, +Llama-xLAM-2-8b-fc-r-encrypted,16000,100,10,1,,, +Llama-xLAM-2-8b-fc-r-encrypted,16000,100,30,3,,, +Llama-xLAM-2-8b-fc-r-encrypted,16000,100,50,5,,, +Llama-xLAM-2-8b-fc-r-encrypted,16000,100,80,8,,, \ No newline at end of file diff --git a/benchmarking/benchmarking_bundles/datakrypto-complete-non_encrypted-model_configs.csv b/benchmarking/benchmarking_bundles/datakrypto-complete-non_encrypted-model_configs.csv new file mode 100644 index 000000000..5d6e2d144 --- /dev/null +++ b/benchmarking/benchmarking_bundles/datakrypto-complete-non_encrypted-model_configs.csv @@ -0,0 +1,17 @@ +model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size +Llama-xLAM-2-8b-fc-r,3900,100,10,1,,, +Llama-xLAM-2-8b-fc-r,3900,100,30,3,,, +Llama-xLAM-2-8b-fc-r,3900,100,50,5,,, +Llama-xLAM-2-8b-fc-r,3900,100,80,8,,, +Llama-xLAM-2-8b-fc-r,3900,100,160,16,,, +Llama-xLAM-2-8b-fc-r,3900,100,320,32,,, +Llama-xLAM-2-8b-fc-r,8000,100,10,1,,, +Llama-xLAM-2-8b-fc-r,8000,100,30,3,,, +Llama-xLAM-2-8b-fc-r,8000,100,50,5,,, +Llama-xLAM-2-8b-fc-r,8000,100,80,8,,, +Llama-xLAM-2-8b-fc-r,8000,100,160,16,,, +Llama-xLAM-2-8b-fc-r,8000,100,320,32,,, +Llama-xLAM-2-8b-fc-r,16000,100,10,1,,, +Llama-xLAM-2-8b-fc-r,16000,100,30,3,,, +Llama-xLAM-2-8b-fc-r,16000,100,50,5,,, +Llama-xLAM-2-8b-fc-r,16000,100,80,8,,, \ No newline at end of file From 7de968433c331b329061625c88583bfaa06feff6 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Fri, 8 May 2026 11:24:39 -0500 Subject: [PATCH 15/17] last run --- benchmarking/benchmarking_bundles/config.yaml | 4 +-- .../model_configs_example.csv | 28 +++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/benchmarking/benchmarking_bundles/config.yaml b/benchmarking/benchmarking_bundles/config.yaml index 13a2b5e7f..a44af786a 100644 --- a/benchmarking/benchmarking_bundles/config.yaml +++ b/benchmarking/benchmarking_bundles/config.yaml @@ -1,7 +1,7 @@ model_configs_path: '../benchmarking/benchmarking_bundles/model_configs_example.csv' llm_api: 'sncloud' -output_files_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted_multiple' -consolidated_results_dir: '../benchmarking/data/bundle_tests/datakrypto/speed_bench_test_encrypted_multiple/consolidated_results' +output_files_dir: '../benchmarking/data/datakrypto/high_ss/speed_bench_test_encrypted_multiple' +consolidated_results_dir: '../benchmarking/data/datakrypto/high_ss/speed_bench_test_encrypted_multiple/consolidated_results' timeout: 3600 time_delay: 0 # Row-level concurrency diff --git a/benchmarking/benchmarking_bundles/model_configs_example.csv b/benchmarking/benchmarking_bundles/model_configs_example.csv index a7391adf0..acfaa92ab 100644 --- a/benchmarking/benchmarking_bundles/model_configs_example.csv +++ b/benchmarking/benchmarking_bundles/model_configs_example.csv @@ -1,13 +1,17 @@ model_name,input_tokens,output_tokens,num_requests,concurrent_requests,qps,qps_distribution,multimodal_img_size -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,10,1,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,20,2,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,40,4,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,80,8,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,160,16,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,100,320,32,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,10,1,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,20,2,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,40,4,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,80,8,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,160,16,,, -Llama-xLAM-2-8b-fc-r-encrypted,2000,1024,320,32,,, \ No newline at end of file +Llama-xLAM-2-8b-fc-r,3900,100,10,1,,, +Llama-xLAM-2-8b-fc-r,3900,100,30,3,,, +Llama-xLAM-2-8b-fc-r,3900,100,50,5,,, +Llama-xLAM-2-8b-fc-r,3900,100,80,8,,, +Llama-xLAM-2-8b-fc-r,3900,100,160,16,,, +Llama-xLAM-2-8b-fc-r,3900,100,320,32,,, +Llama-xLAM-2-8b-fc-r,8000,100,10,1,,, +Llama-xLAM-2-8b-fc-r,8000,100,30,3,,, +Llama-xLAM-2-8b-fc-r,8000,100,50,5,,, +Llama-xLAM-2-8b-fc-r,8000,100,80,8,,, +Llama-xLAM-2-8b-fc-r,8000,100,160,16,,, +Llama-xLAM-2-8b-fc-r,8000,100,320,32,,, +Llama-xLAM-2-8b-fc-r,16000,100,10,1,,, +Llama-xLAM-2-8b-fc-r,16000,100,30,3,,, +Llama-xLAM-2-8b-fc-r,16000,100,50,5,,, +Llama-xLAM-2-8b-fc-r,16000,100,80,8,,, \ No newline at end of file From 12e6697b220ae8176a6e0c238b191c107dbf3cdb Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Fri, 8 May 2026 11:25:00 -0500 Subject: [PATCH 16/17] updated notebook with break up by input size --- ...-performance-analysis-complete-tests.ipynb | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) create mode 100644 benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb diff --git a/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb new file mode 100644 index 000000000..671863f0a --- /dev/null +++ b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb @@ -0,0 +1,308 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "cell-setup", + "metadata": {}, + "outputs": [], + "source": "import os\nimport sys\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\n\nwarnings.filterwarnings('ignore')\npd.set_option('display.float_format', '{:.4f}'.format)\npd.set_option('display.max_columns', 50)\n\nfor rel_path in ['../', '../../', '../../../']:\n abs_path = os.path.abspath(rel_path)\n if abs_path not in sys.path:\n sys.path.insert(0, abs_path)\n\nfrom benchmarking.utils import read_perf_eval_json_files\n\nCOLOR_MAP = {'Encrypted': '#EF553B', 'Non-Encrypted': '#636EFA'}\nSYMBOL_MAP = {'Encrypted': 'circle', 'Non-Encrypted': 'square'}\nCONC_ORDER = [1, 3, 5, 8, 16, 32]\nCONC_STR = [str(c) for c in CONC_ORDER]\nINPUT_ORDER = [3900, 8000, 16000]\nINPUT_LABELS = [f'{n:,} input tokens' for n in INPUT_ORDER]\n\nprint('Setup complete')" + }, + { + "cell_type": "markdown", + "id": "cell-title", + "metadata": {}, + "source": "# DataKrypto TEE Performance Analysis\n## Encrypted vs Non-Encrypted Model — Benchmarking Report\n\n---\n\n### Architecture\n\n```\nNon-Encrypted:\n Client ──────────────────────────► SambaNova Inference Server\n (1 network hop)\n\nEncrypted:\n Client ──► DataKrypto TEE ───────► SambaNova Inference Server\n │ encrypts input returns encrypted chunks\n │ decrypts each output ◄─────────────────────────┘\n │ chunk (streaming)\n └──► Client\n (2 network hops total)\n```\n\n### Models\n| Model | Description |\n|-------|-------------|\n| `Llama-xLAM-2-8b-fc-r` | Base model (plain inference) |\n| `Llama-xLAM-2-8b-fc-r-encrypted` | Runs through DataKrypto TEE |\n\n> Note: The two models are served by **separate SambaNova endpoints** which may have\n> different hardware allocations or decode configurations. Any baseline performance\n> difference between them is an endpoint-level characteristic — not caused by the TEE.\n\n### Test Matrix\n- **Input tokens**: 3,900 / 8,000 / 16,000 (varied — primary axis of analysis)\n- **Output tokens**: 100 (fixed)\n- **Concurrencies**: 1, 3, 5, 8, 16, 32\n- Each concurrency level = **N separate HTTP requests sent simultaneously** (not a single batch API call — N independent requests hitting the server at the same time, which the server can dynamically batch together for inference)\n- **Multi Run (10x)**: 10 sequential rounds of N simultaneous requests — provides statistical robustness and tests sustained server/TEE behavior over time\n\n> All plots in this report are **faceted by Input Tokens** so encryption / network / server-side\n> behavior can be compared directly across prompt sizes.\n\n### TEE Overhead Sources\n1. **Input Encryption** — encrypts the prompt (grows with input token count)\n2. **Output Decryption** — decrypts each streaming token chunk (grows with output tokens)\n3. **Network Hop** — extra Client → TEE → Server roundtrip (dominant overhead)\n\n> **TEE capacity constraint**: The TEE has **8 cores** and processes encryption/decryption\n> sequentially per core. At concurrency > 8, the TEE queue fills up causing requests to wait,\n> which means concurrent requests may arrive at the inference server **staggered** rather than\n> simultaneously — reducing the effective batch size the server sees.\n\n---" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-load", + "metadata": {}, + "outputs": [], + "source": "DATA_ROOT = os.path.abspath('../../data/datakrypto')\n\nDATASETS = {\n 'enc_multiple': {\n 'consolidated': f'{DATA_ROOT}/high_ss/speed_bench_test_encrypted_multiple/consolidated_results/20260506-120053.565163-complete.xlsx',\n 'run_dir': f'{DATA_ROOT}/high_ss/speed_bench_test_encrypted_multiple/20260506-120053.565163-complete',\n 'encrypted': True,\n 'run_type': 'Multi Run (10x)',\n 'label': 'Encrypted',\n },\n 'plain_multiple': {\n 'consolidated': f'{DATA_ROOT}/high_ss/speed_bench_test_nonencrypted_multiple/consolidated_results/20260506-121009.676284.xlsx',\n 'run_dir': f'{DATA_ROOT}/high_ss/speed_bench_test_nonencrypted_multiple/20260506-121009.676284',\n 'encrypted': False,\n 'run_type': 'Multi Run (10x)',\n 'label': 'Non-Encrypted',\n },\n}\n\ndfs = []\nfor key, meta in DATASETS.items():\n df = pd.read_excel(meta['consolidated'])\n df['dataset_key'] = key\n df['encrypted'] = meta['encrypted']\n df['run_type'] = meta['run_type']\n df['label'] = meta['label']\n dfs.append(df)\n\ndf_all = pd.concat(dfs, ignore_index=True)\n\n# Derived columns — input-token labels are now the primary facet\ndf_all['in_tokens_label'] = df_all['num_input_tokens'].apply(lambda n: f'{int(n):,} input tokens')\ndf_all['out_tokens_label'] = df_all['num_output_tokens'].astype(str) + ' output tokens'\ndf_all['total_requests'] = df_all['num_completed_requests'] + df_all['number_errors']\ndf_all['error_rate_pct'] = (df_all['number_errors'] / df_all['total_requests'].replace(0, np.nan)) * 100\ndf_all['completion_rate_pct'] = 100 - df_all['error_rate_pct']\n\n# Ordered categoricals for consistent facet ordering\ndf_all['in_tokens_label'] = pd.Categorical(\n df_all['in_tokens_label'], categories=INPUT_LABELS, ordered=True\n)\n\nprint(f'Loaded {len(df_all)} rows across {df_all[\"dataset_key\"].nunique()} datasets')\nprint(f'Input tokens: {sorted(df_all[\"num_input_tokens\"].unique())}')\nprint(f'Output tokens: {sorted(df_all[\"num_output_tokens\"].unique())}')\nprint(f'Concurrencies: {sorted(df_all[\"num_concurrent_requests\"].unique())}')\ndf_all.groupby(['label', 'in_tokens_label'])[['num_concurrent_requests']].count().rename(\n columns={'num_concurrent_requests': 'scenarios'}\n)" + }, + { + "cell_type": "markdown", + "id": "cell-overview-hdr", + "metadata": {}, + "source": [ + "## 1. Dataset Overview" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-overview", + "metadata": {}, + "outputs": [], + "source": "cols = ['label',\n 'num_input_tokens',\n 'num_output_tokens',\n 'num_concurrent_requests',\n 'num_completed_requests',\n 'number_errors',\n 'error_rate_pct'\n ]\noverview = df_all[cols].copy()\noverview.columns = ['Model',\n 'Input Tokens',\n 'Output Tokens',\n 'Concurrency',\n 'Completed',\n 'Errors',\n 'Error Rate (%)'\n ]\noverview['Error Rate (%)'] = overview['Error Rate (%)'].fillna(0).round(1)\noverview = overview.sort_values(['Input Tokens', 'Model', 'Concurrency'])\n\ndef _highlight_errors(row):\n if row['Errors'] > 0:\n return ['background-color: #ffdddd'] * len(row)\n return [''] * len(row)\n\noverview.style.apply(_highlight_errors, axis=1).format({'Error Rate (%)': '{:.1f}%'})" + }, + { + "cell_type": "markdown", + "id": "cell-errors-hdr", + "metadata": {}, + "source": [ + "## 2. Error & Completion Rate Analysis\n", + "\n", + "The TEE has **8 cores** processing encryption/decryption sequentially.\n", + "At concurrency > 8, the TEE queue fills up and requests may time out or be rejected,\n", + "producing errors on the encrypted model only. The plain model should show zero errors." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-errors-chart", + "metadata": {}, + "outputs": [], + "source": "fig = px.bar(\n df_all,\n x='num_concurrent_requests',\n y='error_rate_pct',\n color='label',\n facet_col='in_tokens_label',\n barmode='group',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'error_rate_pct': 'Error Rate (%)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Request Error Rate by Concurrency — faceted by Input Tokens
'\n 'Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). '\n 'Non-Encrypted should be 0% throughout.'\n ),\n)\nfig.update_layout(height=420, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-reqmin-chart", + "metadata": {}, + "outputs": [], + "source": "# Completed requests per minute — real system throughput capacity\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='num_completed_requests_per_min',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'num_completed_requests_per_min': 'Completed Requests / min',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'System Throughput: Completed Requests per Minute — faceted by Input Tokens
'\n 'Indicator of system capacity. '\n 'Encrypted throughput is increasingly limited by TEE queueing as input tokens grow '\n '(more bytes to encrypt) and at higher concurrencies.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "markdown", + "id": "cell-server-hdr", + "metadata": {}, + "source": "## 3. Server-Side Metrics — Behavior Across Input Sizes\n\nServer-side metrics measure what happens **inside the SambaNova engine**, after the TEE has\nrelayed the request. They tell us whether the TEE itself slows the model — and they isolate\nthe **input-size effect** on prefill vs. decode.\n\n**What to look for as input tokens grow (3,900 → 8,000 → 16,000):**\n- **Server TTFT** rises (prefill scales with input length)\n- **Server tok/s** for decode should be roughly stable (decode rate is mostly independent\n of input length once prefill is done)\n- **Server E2E latency** rises mainly because of prefill, not because of the TEE\n\n**TEE de-batching effect:** because the TEE processes encryption sequentially per core,\nconcurrent requests reach the inference server staggered. This often keeps the encrypted path's\n**effective server batch size smaller**, so its server-side TTFT can be lower than the\nnon-encrypted path at high concurrency." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-ttft", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_ttft_s_p50': 'Server TTFT p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server Time to First Token — p50 (faceted by Input Tokens)
'\n 'TTFT grows with input size (longer prefill). Watch for the de-batching effect: '\n 'at high concurrency, encrypted server TTFT can be lower than non-encrypted because '\n 'staggered TEE arrivals shrink the effective server batch.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-toks", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_output_token_per_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_output_token_per_s_p50': 'Server Output Tok/s p50 (per request)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server Output Throughput per Request — p50 (faceted by Input Tokens)
'\n 'Decode rate should be roughly independent of input size. Any large gap between '\n 'encrypted and non-encrypted in the same facet would point at endpoint configuration '\n 'differences, not the TEE itself.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-e2e", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_end_to_end_latency_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_end_to_end_latency_s_p50': 'Server E2E Latency p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title='Server End-to-End Latency — p50 (faceted by Input Tokens)',\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-server-delta", + "metadata": {}, + "outputs": [], + "source": "# Server metrics delta table — Encrypted minus Non-Encrypted (per Input Tokens × Concurrency)\nDIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\ndf_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n\nserver_metrics = [\n ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n ('server_end_to_end_latency_s_p50','Server E2E p50 (s)'),\n]\n\ndelta_rows = []\nfor col, label in server_metrics:\n if col not in df_enc_s.columns:\n continue\n for idx in df_enc_s.index:\n if idx not in df_plain_s.index:\n continue\n enc_val = df_enc_s.loc[idx, col]\n plain_val = df_plain_s.loc[idx, col]\n if pd.isna(enc_val) or pd.isna(plain_val):\n continue\n delta = enc_val - plain_val\n pct_chg = delta / plain_val * 100 if plain_val != 0 else np.nan\n delta_rows.append({\n 'Metric': label,\n 'Input Tokens': idx[0],\n 'Output Tokens': idx[1],\n 'Concurrency': idx[2],\n 'Non-Encrypted': plain_val,\n 'Encrypted': enc_val,\n 'Delta': delta,\n '% Change': pct_chg,\n })\n\ndf_server_delta = pd.DataFrame(delta_rows)\ndf_server_delta = df_server_delta.sort_values(['Metric', 'Input Tokens', 'Concurrency'])\n\ndef _pct_color(val):\n if pd.isna(val): return ''\n if val > 50: return 'background-color: #ffaaaa'\n if val > 20: return 'background-color: #ffd8aa'\n if val > 0: return 'background-color: #fffacc'\n if val < -20: return 'background-color: #aaffaa'\n return ''\n\ndf_server_delta.style \\\n .applymap(_pct_color, subset=['% Change']) \\\n .format({\n 'Non-Encrypted': '{:.4f}',\n 'Encrypted': '{:.4f}',\n 'Delta': '{:+.4f}',\n '% Change': '{:+.1f}%',\n })" + }, + { + "cell_type": "markdown", + "id": "cell-tee-hdr", + "metadata": {}, + "source": "## 4. TEE Overhead Decomposition (Encrypted Model Only)\n\nThree measurable components are returned by the TEE per request:\n\n| Component | Description | Expected Behavior vs Input Tokens |\n|-----------|-------------|----------------------------------|\n| **Input Encryption** | Time to encrypt the prompt before sending to server | grows with input token count |\n| **Output Decryption** | Cumulative time to decrypt all streaming output chunks | ~constant (output is fixed at 100) |\n| **Network Hop** | Round-trip latency through the TEE (Client→TEE→Server→TEE→Client) | grows with concurrency (TEE queue) and payload size |\n\n> Faceting by input tokens lets us see how much of the TEE overhead is driven by **prompt size**\n> as opposed to concurrency." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-tee-stack", + "metadata": {}, + "outputs": [], + "source": "df_tee = df_all[df_all['label'] == 'Encrypted'].copy()\n\n# Convert ms → s for consistent units with latency charts\ndf_tee['Network Hop'] = df_tee['server_network_latency_ms_mean'] / 1000\ndf_tee['Input Encryption'] = df_tee['total_encryption_time_ms_mean'] / 1000\ndf_tee['Output Decryption'] = df_tee['total_decryption_time_ms_mean'] / 1000\n\nTEE_ID_COLS = ['in_tokens_label', 'num_concurrent_requests']\nTEE_VAL_COLS = ['Network Hop', 'Input Encryption', 'Output Decryption']\n\ndf_tee_melt = df_tee[TEE_ID_COLS + TEE_VAL_COLS].melt(\n id_vars=TEE_ID_COLS, var_name='Component', value_name='Overhead (s)'\n)\n\nCOMP_COLORS = {\n 'Network Hop': '#FF7F0E',\n 'Input Encryption': '#D62728',\n 'Output Decryption': '#2CA02C',\n}\n\nfig = px.bar(\n df_tee_melt,\n x='num_concurrent_requests',\n y='Overhead (s)',\n color='Component',\n facet_col='in_tokens_label',\n barmode='stack',\n color_discrete_map=COMP_COLORS,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'TEE Overhead Breakdown per Request — faceted by Input Tokens
'\n 'Network Hop dominates. Encryption grows with input size (more bytes to encrypt). '\n 'Decryption is roughly constant since output tokens are fixed at 100.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-network-latency", + "metadata": {}, + "outputs": [], + "source": "# Network latency growth — most important overhead component\nfig = px.line(\n df_tee,\n x='num_concurrent_requests',\n y='server_network_latency_ms_mean',\n color='in_tokens_label',\n facet_col='in_tokens_label',\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_network_latency_ms_mean': 'TEE Network Latency — Mean (ms)',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'TEE Network Latency vs Concurrency — faceted by Input Tokens
'\n 'Grows with concurrency (TEE queueing) AND with input tokens '\n '(larger encrypted payload to ship).'\n ),\n)\nfig.update_layout(height=420, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-enc-dec-times", + "metadata": {}, + "outputs": [], + "source": "# Encryption and decryption times detail — one line per Input Tokens\nfig = make_subplots(\n rows=1, cols=2,\n subplot_titles=['Input Encryption Time (ms)', 'Output Decryption Time (ms)'],\n)\n\n_input_colors = {3900: '#1f77b4', 8000: '#2ca02c', 16000: '#ff7f0e'}\n_shown = set()\n\nfor in_tok, color in _input_colors.items():\n sub = df_tee[df_tee['num_input_tokens'] == in_tok].sort_values('num_concurrent_requests')\n name = f'{in_tok:,} input tokens'\n show = name not in _shown\n kw = dict(x=sub['num_concurrent_requests'], mode='lines+markers',\n name=name, line=dict(color=color),\n legendgroup=name, showlegend=show)\n fig.add_trace(go.Scatter(y=sub['total_encryption_time_ms_mean'], **kw), row=1, col=1)\n kw['showlegend'] = False\n fig.add_trace(go.Scatter(y=sub['total_decryption_time_ms_mean'], **kw), row=1, col=2)\n _shown.add(name)\n\nfig.update_xaxes(\n type='log', tickvals=CONC_ORDER, ticktext=CONC_STR,\n title_text='Concurrency (log scale)',\n)\nfig.update_yaxes(title_text='Time (ms)', col=1)\nfig.update_yaxes(title_text='Time (ms)', col=2)\nfig.update_layout(\n height=420, width=1200, template='plotly_white',\n legend_title='Input Tokens',\n title=(\n 'TEE Encryption & Decryption Times — by Input Tokens
'\n 'Encryption scales with input size (more bytes per prompt). '\n 'Decryption is roughly flat across input sizes since output is fixed at 100 tokens.'\n ),\n)\nfig.show()" + }, + { + "cell_type": "markdown", + "id": "cell-client-hdr", + "metadata": {}, + "source": [ + "## 5. Client-Side Metrics — End-User Experience\n", + "\n", + "Client metrics include the full roundtrip: **Client → (TEE) → Server → (TEE) → Client**.\n", + "\n", + "The gap between encrypted and non-encrypted client metrics is the\n", + "**observable user-facing cost** of the TEE encryption layer." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-client-ttft", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_ttft_s_p50': 'Client TTFT p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client Time to First Token — p50 (faceted by Input Tokens)
'\n 'Both models slow down as input grows (longer prefill). '\n 'Encrypted carries TEE network + encryption overhead on top — gap typically widens '\n 'with concurrency, but de-batching can flip it at high concurrency on smaller prompts.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-ttft-attribution", + "metadata": {}, + "outputs": [], + "source": "# Client TTFT overhead attribution: stacked TEE components vs total delta\nDIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_enc_a = df_all[df_all['label'] == 'Encrypted'].copy()\ndf_plain_a = df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n columns={'client_ttft_s_p50': 'client_ttft_plain'}\n)\ndf_attr = df_enc_a.merge(df_plain_a, on=DIMS)\n\ndf_attr['client_ttft_delta'] = df_attr['client_ttft_s_p50'] - df_attr['client_ttft_plain']\ndf_attr['Network Hop (s)'] = df_attr['server_network_latency_ms_mean'] / 1000\ndf_attr['Input Encryption (s)'] = df_attr['total_encryption_time_ms_mean'] / 1000\ndf_attr['Output Decryption (s)']= df_attr['total_decryption_time_ms_mean'] / 1000\ndf_attr['Residual (s)'] = (\n df_attr['client_ttft_delta']\n - df_attr['Network Hop (s)']\n - df_attr['Input Encryption (s)']\n - df_attr['Output Decryption (s)']\n).clip(lower=0)\n\nATTR_COLS = ['Network Hop (s)', 'Input Encryption (s)', 'Output Decryption (s)', 'Residual (s)']\nATTR_COLORS = {\n 'Network Hop (s)': '#FF7F0E',\n 'Input Encryption (s)': '#D62728',\n 'Output Decryption (s)': '#2CA02C',\n 'Residual (s)': '#9467BD',\n}\n\ndf_attr_melt = df_attr.melt(\n id_vars=['in_tokens_label', 'num_concurrent_requests', 'client_ttft_delta'],\n value_vars=ATTR_COLS, var_name='Component', value_name='Overhead (s)',\n).dropna(subset=['Overhead (s)'])\n\nfig = px.bar(\n df_attr_melt,\n x='num_concurrent_requests',\n y='Overhead (s)',\n color='Component',\n facet_col='in_tokens_label',\n barmode='stack',\n color_discrete_map=ATTR_COLORS,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta — by Input Tokens
'\n 'Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. '\n 'Residual = delta not fully explained by TEE metrics (measurement noise / endpoint diff).'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-client-e2e", + "metadata": {}, + "outputs": [], + "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_end_to_end_latency_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_end_to_end_latency_s_p50': 'Client E2E Latency p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client End-to-End Latency — p50 (faceted by Input Tokens)
'\n 'Full request duration as observed by the client. '\n 'Both prefill (input size) and TEE queueing (concurrency) push this up.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-client-toks", + "metadata": {}, + "outputs": [], + "source": "# Per-request client generation speed\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_output_token_per_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_output_token_per_s_p50': 'Client Output Tok/s p50 (per request)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client Output Throughput per Request — p50 (faceted by Input Tokens)
'\n 'After the first token, subsequent tokens stream at this rate. '\n 'Encrypted is bounded by TEE streaming decryption; '\n 'Non-Encrypted by server generation at high concurrency.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-total-throughput", + "metadata": {}, + "outputs": [], + "source": "# Total system throughput — aggregate across all concurrent requests\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_total_output_throughput',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_total_output_throughput': 'Total Output Throughput (tok/s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Total Client Output Throughput — All Concurrent Requests (faceted by Input Tokens)
'\n 'Non-Encrypted scales nearly linearly with concurrency. '\n 'Encrypted ceiling drops as input tokens grow because each request takes longer to '\n 'encrypt + ship through the TEE.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + }, + { + "cell_type": "markdown", + "id": "cell-dist-hdr", + "metadata": {}, + "source": "## 6. Per-Request Distributions\n\nBox plots using individual request data from all 10 rounds, faceted by **Input Tokens**.\nError requests (where `error_code` is set) are excluded." + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-load-individual", + "metadata": {}, + "outputs": [], + "source": "def _parse_fname(fname):\n \"\"\"Extract (input_tokens, output_tokens, concurrency) from benchmark filename.\n\n Filename format:\n synthetic______stream__*\n \"\"\"\n base = os.path.basename(str(fname)).replace('_individual_responses.json', '')\n parts = base.split('_')\n try:\n return int(parts[3]), int(parts[4]), int(parts[5])\n except (IndexError, ValueError):\n return None, None, None\n\ndfs_ind = []\nfor key, meta in DATASETS.items():\n try:\n df_ind = read_perf_eval_json_files(meta['run_dir'], type='individual_responses')\n if df_ind.empty:\n continue\n df_ind['label'] = meta['label']\n df_ind['run_type'] = meta['run_type']\n parsed = df_ind['filename'].apply(lambda f: pd.Series(_parse_fname(f)))\n df_ind['num_input_tokens'] = parsed[0]\n df_ind['num_output_tokens'] = parsed[1]\n df_ind['num_concurrent_requests'] = parsed[2]\n dfs_ind.append(df_ind)\n except Exception as e:\n print(f'Warning: could not load {key}: {e}')\n\ndf_individual = pd.concat(dfs_ind, ignore_index=True)\ndf_individual = df_individual.dropna(\n subset=['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests', 'client_ttft_s']\n)\ndf_individual['num_input_tokens'] = df_individual['num_input_tokens'].astype(int)\ndf_individual['num_output_tokens'] = df_individual['num_output_tokens'].astype(int)\ndf_individual['num_concurrent_requests'] = df_individual['num_concurrent_requests'].astype(int)\ndf_individual['in_tokens_label'] = df_individual['num_input_tokens'].apply(lambda n: f'{n:,} input tokens')\ndf_individual['concurrency_str'] = df_individual['num_concurrent_requests'].astype(str)\ndf_individual['is_error'] = df_individual['error_code'].notna()\ndf_individual['in_tokens_label'] = pd.Categorical(\n df_individual['in_tokens_label'], categories=INPUT_LABELS, ordered=True\n)\n\nprint(f'Loaded {len(df_individual):,} individual request records')\ndf_individual.groupby(['label', 'in_tokens_label', 'is_error'])[['client_ttft_s']].count().rename(\n columns={'client_ttft_s': 'count'}\n)" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-box-client-ttft", + "metadata": {}, + "outputs": [], + "source": "df_box = df_individual[~df_individual['is_error']].copy()\n\nfig = px.box(\n df_box,\n x='concurrency_str',\n y='client_ttft_s',\n color='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n points='outliers',\n labels={\n 'concurrency_str': 'Concurrency',\n 'client_ttft_s': 'Client TTFT (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client TTFT Distribution per Concurrency — faceted by Input Tokens
'\n 'Encrypted shows higher median AND wider spread due to variable TEE network latency. '\n 'Spread grows with both input size and concurrency.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-box-server-ttft", + "metadata": {}, + "outputs": [], + "source": "fig = px.box(\n df_box,\n x='concurrency_str',\n y='server_ttft_s',\n color='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n points='outliers',\n labels={\n 'concurrency_str': 'Concurrency',\n 'server_ttft_s': 'Server TTFT (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server TTFT Distribution per Concurrency — faceted by Input Tokens
'\n 'Server-side distribution. At medium concurrency, encrypted may show LOWER server TTFT '\n 'because TEE de-batching reduces the effective batch size seen by the server.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.show()" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-scatter-tee", + "metadata": {}, + "outputs": [], + "source": "# Per-request: TEE network latency vs server TTFT (encrypted only), one column per Input Tokens\ndf_enc_ind = df_individual[\n (df_individual['label'] == 'Encrypted') &\n (~df_individual['is_error']) &\n (df_individual['server_network_latency_ms'].notna())\n].copy()\n\nfig = px.scatter(\n df_enc_ind,\n x='server_ttft_s',\n y='server_network_latency_ms',\n color='concurrency_str',\n facet_col='in_tokens_label',\n opacity=0.55,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'server_ttft_s': 'Server TTFT (s)',\n 'server_network_latency_ms': 'TEE Network Latency (ms)',\n 'in_tokens_label': 'Input Tokens',\n 'concurrency_str': 'Concurrency',\n },\n title=(\n 'Per-Request: TEE Network Latency vs Server TTFT — Encrypted (faceted by Input Tokens)
'\n 'How network latency varies relative to server prefill time. '\n 'A flatter horizontal spread = network latency is independent of server load.'\n ),\n)\nfig.update_layout(height=420, width=1300, template='plotly_white')\nfig.show()" + }, + { + "cell_type": "markdown", + "id": "cell-summary-hdr", + "metadata": {}, + "source": [ + "## 7. Summary\n", + "\n", + "### Full Metric Comparison" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-summary-table", + "metadata": {}, + "outputs": [], + "source": "DIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\nALL_METRICS = [\n ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n ('server_end_to_end_latency_s_p50', 'Server E2E p50 (s)'),\n ('client_ttft_s_p50', 'Client TTFT p50 (s)'),\n ('client_end_to_end_latency_s_p50', 'Client E2E p50 (s)'),\n ('client_output_token_per_s_p50', 'Client Tok/s p50'),\n ('client_total_output_throughput', 'Total Throughput (tok/s)'),\n ('num_completed_requests_per_min', 'Req / min'),\n ('error_rate_pct', 'Error Rate (%)'),\n]\n\ndf_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\ndf_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n\nrows = []\nfor col, label in ALL_METRICS:\n if col not in df_enc_s.columns:\n continue\n for idx in df_enc_s.index:\n if idx not in df_plain_s.index:\n continue\n enc_v = df_enc_s.loc[idx, col]\n plain_v = df_plain_s.loc[idx, col]\n if pd.isna(enc_v) and pd.isna(plain_v):\n continue\n delta = enc_v - plain_v if pd.notna(enc_v) and pd.notna(plain_v) else np.nan\n pct_chg = delta / plain_v * 100 if pd.notna(delta) and plain_v != 0 else np.nan\n rows.append({\n 'Metric': label,\n 'Input Tokens': idx[0],\n 'Output Tokens': idx[1],\n 'Concurrency': idx[2],\n 'Non-Encrypted': plain_v,\n 'Encrypted': enc_v,\n 'Delta': delta,\n '% Change': pct_chg,\n })\n\ndf_summary = pd.DataFrame(rows).sort_values(\n ['Metric', 'Input Tokens', 'Concurrency']\n)\n\ndef _pct_color(val):\n if pd.isna(val): return ''\n if val > 100: return 'background-color: #ff6666'\n if val > 50: return 'background-color: #ffaaaa'\n if val > 20: return 'background-color: #ffd8aa'\n if val > 0: return 'background-color: #fffacc'\n if val < -20: return 'background-color: #aaffaa'\n return ''\n\ndf_summary.style \\\n .applymap(_pct_color, subset=['% Change']) \\\n .format({\n 'Non-Encrypted': '{:.3f}',\n 'Encrypted': '{:.3f}',\n 'Delta': '{:+.3f}',\n '% Change': '{:+.1f}%',\n }, na_rep='—')" + }, + { + "cell_type": "markdown", + "id": "cell-tee-overhead-hdr", + "metadata": {}, + "source": [ + "### TEE Overhead Attribution per Scenario" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cell-tee-overhead-table", + "metadata": {}, + "outputs": [], + "source": "DIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_tee_oh = df_all[df_all['label'] == 'Encrypted'].copy()\ndf_tee_oh = df_tee_oh.merge(\n df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n columns={'client_ttft_s_p50': 'client_ttft_plain'}\n ),\n on=DIMS,\n)\n\ndf_tee_oh['enc_time_s'] = df_tee_oh['total_encryption_time_ms_mean'] / 1000\ndf_tee_oh['dec_time_s'] = df_tee_oh['total_decryption_time_ms_mean'] / 1000\ndf_tee_oh['network_s'] = df_tee_oh['server_network_latency_ms_mean'] / 1000\ndf_tee_oh['tee_total_s'] = df_tee_oh['enc_time_s'] + df_tee_oh['dec_time_s'] + df_tee_oh['network_s']\ndf_tee_oh['ttft_delta_s'] = df_tee_oh['client_ttft_s_p50'] - df_tee_oh['client_ttft_plain']\ndf_tee_oh['network_pct'] = df_tee_oh['network_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['enc_pct'] = df_tee_oh['enc_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['dec_pct'] = df_tee_oh['dec_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['tee_total_pct'] = df_tee_oh['tee_total_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n\nDISPLAY = {\n 'num_input_tokens': 'Input Tokens',\n 'num_output_tokens': 'Output Tokens',\n 'num_concurrent_requests': 'Concurrency',\n 'client_ttft_plain': 'Plain TTFT (s)',\n 'client_ttft_s_p50': 'Enc TTFT (s)',\n 'ttft_delta_s': 'Delta (s)',\n 'enc_time_s': 'Encryption (s)',\n 'dec_time_s': 'Decryption (s)',\n 'network_s': 'Network Hop (s)',\n 'tee_total_s': 'TEE Total (s)',\n 'tee_total_pct': 'TEE % of Enc TTFT',\n 'network_pct': 'Network %',\n 'enc_pct': 'Encrypt %',\n 'dec_pct': 'Decrypt %',\n}\n\ndf_tee_display = (\n df_tee_oh[list(DISPLAY.keys())]\n .rename(columns=DISPLAY)\n .sort_values(['Input Tokens', 'Concurrency'])\n)\n\npct_cols = [c for c in df_tee_display.columns if '%' in c]\ns_cols = [c for c in df_tee_display.columns if '(s)' in c]\n\ndf_tee_display.style \\\n .background_gradient(subset=['TEE % of Enc TTFT'], cmap='YlOrRd') \\\n .format({c: '{:.1f}%' for c in pct_cols}) \\\n .format({c: '{:.4f}' for c in s_cols}, na_rep='—')" + }, + { + "cell_type": "code", + "execution_count": null, + "id": "56a895dd", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7cf9ba4", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dea813eb", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "benchmarking_venv", + "language": "python", + "name": "benchmarking_venv" + }, + "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.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From 556e4ddfd4e6667a812a7c75efd90470a3ac9588 Mon Sep 17 00:00:00 2001 From: Rodrigo Maldonado Date: Fri, 8 May 2026 14:25:50 -0500 Subject: [PATCH 17/17] last run using data from vm and ss up to 16k --- ...-performance-analysis-complete-tests.ipynb | 27200 +++++++++++++++- 1 file changed, 27126 insertions(+), 74 deletions(-) diff --git a/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb index 671863f0a..1f97de7b9 100644 --- a/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb +++ b/benchmarking/benchmarking_bundles/notebooks/datakrypto-tee-performance-analysis-complete-tests.ipynb @@ -2,25 +2,252 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "cell-setup", "metadata": {}, - "outputs": [], - "source": "import os\nimport sys\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport plotly.express as px\nimport plotly.graph_objects as go\nfrom plotly.subplots import make_subplots\n\nwarnings.filterwarnings('ignore')\npd.set_option('display.float_format', '{:.4f}'.format)\npd.set_option('display.max_columns', 50)\n\nfor rel_path in ['../', '../../', '../../../']:\n abs_path = os.path.abspath(rel_path)\n if abs_path not in sys.path:\n sys.path.insert(0, abs_path)\n\nfrom benchmarking.utils import read_perf_eval_json_files\n\nCOLOR_MAP = {'Encrypted': '#EF553B', 'Non-Encrypted': '#636EFA'}\nSYMBOL_MAP = {'Encrypted': 'circle', 'Non-Encrypted': 'square'}\nCONC_ORDER = [1, 3, 5, 8, 16, 32]\nCONC_STR = [str(c) for c in CONC_ORDER]\nINPUT_ORDER = [3900, 8000, 16000]\nINPUT_LABELS = [f'{n:,} input tokens' for n in INPUT_ORDER]\n\nprint('Setup complete')" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Setup complete\n" + ] + } + ], + "source": [ + "import os\n", + "import sys\n", + "import warnings\n", + "import numpy as np\n", + "import pandas as pd\n", + "import plotly.express as px\n", + "import plotly.graph_objects as go\n", + "from plotly.subplots import make_subplots\n", + "\n", + "warnings.filterwarnings('ignore')\n", + "pd.set_option('display.float_format', '{:.4f}'.format)\n", + "pd.set_option('display.max_columns', 50)\n", + "\n", + "for rel_path in ['../', '../../', '../../../']:\n", + " abs_path = os.path.abspath(rel_path)\n", + " if abs_path not in sys.path:\n", + " sys.path.insert(0, abs_path)\n", + "\n", + "from benchmarking.utils import read_perf_eval_json_files\n", + "\n", + "COLOR_MAP = {'Encrypted': '#EF553B', 'Non-Encrypted': '#636EFA'}\n", + "SYMBOL_MAP = {'Encrypted': 'circle', 'Non-Encrypted': 'square'}\n", + "CONC_ORDER = [1, 3, 5, 8, 16, 32]\n", + "CONC_STR = [str(c) for c in CONC_ORDER]\n", + "INPUT_ORDER = [3900, 8000, 16000]\n", + "INPUT_LABELS = [f'{n:,} input tokens' for n in INPUT_ORDER]\n", + "\n", + "print('Setup complete')" + ] }, { "cell_type": "markdown", "id": "cell-title", "metadata": {}, - "source": "# DataKrypto TEE Performance Analysis\n## Encrypted vs Non-Encrypted Model — Benchmarking Report\n\n---\n\n### Architecture\n\n```\nNon-Encrypted:\n Client ──────────────────────────► SambaNova Inference Server\n (1 network hop)\n\nEncrypted:\n Client ──► DataKrypto TEE ───────► SambaNova Inference Server\n │ encrypts input returns encrypted chunks\n │ decrypts each output ◄─────────────────────────┘\n │ chunk (streaming)\n └──► Client\n (2 network hops total)\n```\n\n### Models\n| Model | Description |\n|-------|-------------|\n| `Llama-xLAM-2-8b-fc-r` | Base model (plain inference) |\n| `Llama-xLAM-2-8b-fc-r-encrypted` | Runs through DataKrypto TEE |\n\n> Note: The two models are served by **separate SambaNova endpoints** which may have\n> different hardware allocations or decode configurations. Any baseline performance\n> difference between them is an endpoint-level characteristic — not caused by the TEE.\n\n### Test Matrix\n- **Input tokens**: 3,900 / 8,000 / 16,000 (varied — primary axis of analysis)\n- **Output tokens**: 100 (fixed)\n- **Concurrencies**: 1, 3, 5, 8, 16, 32\n- Each concurrency level = **N separate HTTP requests sent simultaneously** (not a single batch API call — N independent requests hitting the server at the same time, which the server can dynamically batch together for inference)\n- **Multi Run (10x)**: 10 sequential rounds of N simultaneous requests — provides statistical robustness and tests sustained server/TEE behavior over time\n\n> All plots in this report are **faceted by Input Tokens** so encryption / network / server-side\n> behavior can be compared directly across prompt sizes.\n\n### TEE Overhead Sources\n1. **Input Encryption** — encrypts the prompt (grows with input token count)\n2. **Output Decryption** — decrypts each streaming token chunk (grows with output tokens)\n3. **Network Hop** — extra Client → TEE → Server roundtrip (dominant overhead)\n\n> **TEE capacity constraint**: The TEE has **8 cores** and processes encryption/decryption\n> sequentially per core. At concurrency > 8, the TEE queue fills up causing requests to wait,\n> which means concurrent requests may arrive at the inference server **staggered** rather than\n> simultaneously — reducing the effective batch size the server sees.\n\n---" + "source": [ + "# DataKrypto TEE Performance Analysis\n", + "## Encrypted vs Non-Encrypted Model — Benchmarking Report\n", + "\n", + "---\n", + "\n", + "### Architecture\n", + "\n", + "```\n", + "Non-Encrypted:\n", + " Client ──────────────────────────► SambaNova Inference Server\n", + " (1 network hop)\n", + "\n", + "Encrypted:\n", + " Client ──► DataKrypto TEE ───────► SambaNova Inference Server\n", + " │ encrypts input returns encrypted chunks\n", + " │ decrypts each output ◄─────────────────────────┘\n", + " │ chunk (streaming)\n", + " └──► Client\n", + " (2 network hops total)\n", + "```\n", + "\n", + "### Models\n", + "| Model | Description |\n", + "|-------|-------------|\n", + "| `Llama-xLAM-2-8b-fc-r` | Base model (plain inference) |\n", + "| `Llama-xLAM-2-8b-fc-r-encrypted` | Runs through DataKrypto TEE |\n", + "\n", + "> Note: The two models are served by **separate SambaNova endpoints** which may have\n", + "> different hardware allocations or decode configurations. Any baseline performance\n", + "> difference between them is an endpoint-level characteristic — not caused by the TEE.\n", + "\n", + "### Test Matrix\n", + "- **Input tokens**: 2,000 (fixed)\n", + "- **Output tokens**: 100 and 1,024\n", + "- **Concurrencies**: 1, 2, 4, 8, 16, 32\n", + "- Each concurrency level = **N separate HTTP requests sent simultaneously** (not a single batch API call — N independent requests hitting the server at the same time, which the server can dynamically batch together for inference)\n", + "- **Single Run (1x)**: One round of N simultaneous requests — clean first-hit baseline at each concurrency level\n", + "- **Multi Run (10x)**: 10 sequential rounds of the same N simultaneous requests — same per-round server load as Single Run, but repeated 10 times. Provides statistical robustness and tests sustained server/TEE behavior over time\n", + "\n", + "> Key difference: Single and Multi Run have the **same per-round concurrency load**.\n", + "> Multi Run adds statistical reliability (more samples) and reveals sustained-load behavior —\n", + "> it does not increase the number of simultaneous requests per round.\n", + "\n", + "### TEE Overhead Sources\n", + "1. **Input Encryption** — encrypts the prompt (~4–10 ms, near-constant per request)\n", + "2. **Output Decryption** — decrypts each streaming token chunk (grows with output tokens)\n", + "3. **Network Hop** — extra Client → TEE → Server roundtrip (dominant overhead)\n", + "\n", + "> **TEE capacity constraint**: The TEE has **8 cores** and processes encryption/decryption\n", + "> sequentially per core. At concurrency > 8, the TEE queue fills up causing requests to wait,\n", + "> which means concurrent requests may arrive at the inference server **staggered** rather than\n", + "> simultaneously — reducing the effective batch size the server sees.\n", + "\n", + "---" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "cell-load", "metadata": {}, - "outputs": [], - "source": "DATA_ROOT = os.path.abspath('../../data/datakrypto')\n\nDATASETS = {\n 'enc_multiple': {\n 'consolidated': f'{DATA_ROOT}/high_ss/speed_bench_test_encrypted_multiple/consolidated_results/20260506-120053.565163-complete.xlsx',\n 'run_dir': f'{DATA_ROOT}/high_ss/speed_bench_test_encrypted_multiple/20260506-120053.565163-complete',\n 'encrypted': True,\n 'run_type': 'Multi Run (10x)',\n 'label': 'Encrypted',\n },\n 'plain_multiple': {\n 'consolidated': f'{DATA_ROOT}/high_ss/speed_bench_test_nonencrypted_multiple/consolidated_results/20260506-121009.676284.xlsx',\n 'run_dir': f'{DATA_ROOT}/high_ss/speed_bench_test_nonencrypted_multiple/20260506-121009.676284',\n 'encrypted': False,\n 'run_type': 'Multi Run (10x)',\n 'label': 'Non-Encrypted',\n },\n}\n\ndfs = []\nfor key, meta in DATASETS.items():\n df = pd.read_excel(meta['consolidated'])\n df['dataset_key'] = key\n df['encrypted'] = meta['encrypted']\n df['run_type'] = meta['run_type']\n df['label'] = meta['label']\n dfs.append(df)\n\ndf_all = pd.concat(dfs, ignore_index=True)\n\n# Derived columns — input-token labels are now the primary facet\ndf_all['in_tokens_label'] = df_all['num_input_tokens'].apply(lambda n: f'{int(n):,} input tokens')\ndf_all['out_tokens_label'] = df_all['num_output_tokens'].astype(str) + ' output tokens'\ndf_all['total_requests'] = df_all['num_completed_requests'] + df_all['number_errors']\ndf_all['error_rate_pct'] = (df_all['number_errors'] / df_all['total_requests'].replace(0, np.nan)) * 100\ndf_all['completion_rate_pct'] = 100 - df_all['error_rate_pct']\n\n# Ordered categoricals for consistent facet ordering\ndf_all['in_tokens_label'] = pd.Categorical(\n df_all['in_tokens_label'], categories=INPUT_LABELS, ordered=True\n)\n\nprint(f'Loaded {len(df_all)} rows across {df_all[\"dataset_key\"].nunique()} datasets')\nprint(f'Input tokens: {sorted(df_all[\"num_input_tokens\"].unique())}')\nprint(f'Output tokens: {sorted(df_all[\"num_output_tokens\"].unique())}')\nprint(f'Concurrencies: {sorted(df_all[\"num_concurrent_requests\"].unique())}')\ndf_all.groupby(['label', 'in_tokens_label'])[['num_concurrent_requests']].count().rename(\n columns={'num_concurrent_requests': 'scenarios'}\n)" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 32 rows across 2 datasets\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
scenarios
labelrun_type
EncryptedSingle Run (1x)0
Multi Run (10x)16
Non-EncryptedSingle Run (1x)0
Multi Run (10x)16
\n", + "
" + ], + "text/plain": [ + " scenarios\n", + "label run_type \n", + "Encrypted Single Run (1x) 0\n", + " Multi Run (10x) 16\n", + "Non-Encrypted Single Run (1x) 0\n", + " Multi Run (10x) 16" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DATA_ROOT = os.path.abspath('../../data/datakrypto')\n", + "\n", + "DATASETS = {\n", + " # 'enc_simple': {\n", + " # 'consolidated': f'{DATA_ROOT}/speed_bench_test_encrypted_simple/consolidated_results/20260225-155057.028751.xlsx',\n", + " # 'run_dir': f'{DATA_ROOT}/speed_bench_test_encrypted_simple/20260225-155057.028751',\n", + " # 'encrypted': True, \n", + " # 'run_type': 'Single Run (1x)', \n", + " # 'label': 'Encrypted',\n", + " # },\n", + " # 'plain_simple': {\n", + " # 'consolidated': f'{DATA_ROOT}/speed_bench_test_non_encrypted_simple/consolidated_results/20260227-204607.930274.xlsx',\n", + " # 'run_dir': f'{DATA_ROOT}/speed_bench_test_non_encrypted_simple/20260227-204607.930274',\n", + " # 'encrypted': False, \n", + " # 'run_type': 'Single Run (1x)', \n", + " # 'label': 'Non-Encrypted',\n", + " # },\n", + " 'enc_multiple': {\n", + " 'consolidated': f'{DATA_ROOT}/google_vm/high_ss/speed_bench_test_encrypted_multiple/consolidated_results/20260508-163540.131539.xlsx',\n", + " 'run_dir': f'{DATA_ROOT}/google_vm/high_ss/speed_bench_test_encrypted_multiple/20260508-163540.131539',\n", + " 'encrypted': True, \n", + " 'run_type': 'Multi Run (10x)', \n", + " 'label': 'Encrypted',\n", + " },\n", + " 'plain_multiple': {\n", + " 'consolidated': f'{DATA_ROOT}/google_vm/high_ss/speed_bench_test_non_encrypted_multiple/consolidated_results/20260508-174824.647237.xlsx',\n", + " 'run_dir': f'{DATA_ROOT}/google_vm/high_ss/speed_bench_test_non_encrypted_multiple/20260508-174824.647237',\n", + " 'encrypted': False, \n", + " 'run_type': 'Multi Run (10x)', \n", + " 'label': 'Non-Encrypted',\n", + " },\n", + "}\n", + "\n", + "dfs = []\n", + "for key, meta in DATASETS.items():\n", + " df = pd.read_excel(meta['consolidated'])\n", + " df['dataset_key'] = key\n", + " df['encrypted'] = meta['encrypted']\n", + " df['run_type'] = meta['run_type']\n", + " df['label'] = meta['label']\n", + " dfs.append(df)\n", + "\n", + "df_all = pd.concat(dfs, ignore_index=True)\n", + "\n", + "# Derived columns\n", + "df_all['out_tokens_label'] = df_all['num_output_tokens'].astype(str) + ' output tokens'\n", + "df_all['in_tokens_label'] = df_all['num_input_tokens'].astype(str) + ' input tokens'\n", + "df_all['total_requests'] = df_all['num_completed_requests'] + df_all['number_errors']\n", + "df_all['error_rate_pct'] = (df_all['number_errors'] / df_all['total_requests'].replace(0, np.nan)) * 100\n", + "df_all['completion_rate_pct'] = 100 - df_all['error_rate_pct']\n", + "\n", + "# Ordered categorical for consistent facet ordering\n", + "df_all['run_type'] = pd.Categorical(\n", + " df_all['run_type'],\n", + " categories=['Single Run (1x)', 'Multi Run (10x)'],\n", + " ordered=True\n", + ")\n", + "\n", + "print(f'Loaded {len(df_all)} rows across {df_all[\"dataset_key\"].nunique()} datasets')\n", + "df_all.groupby(['label', 'run_type'])[['num_concurrent_requests']].count().rename(columns={'num_concurrent_requests': 'scenarios'})" + ] }, { "cell_type": "markdown", @@ -32,11 +259,427 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "cell-overview", "metadata": {}, - "outputs": [], - "source": "cols = ['label',\n 'num_input_tokens',\n 'num_output_tokens',\n 'num_concurrent_requests',\n 'num_completed_requests',\n 'number_errors',\n 'error_rate_pct'\n ]\noverview = df_all[cols].copy()\noverview.columns = ['Model',\n 'Input Tokens',\n 'Output Tokens',\n 'Concurrency',\n 'Completed',\n 'Errors',\n 'Error Rate (%)'\n ]\noverview['Error Rate (%)'] = overview['Error Rate (%)'].fillna(0).round(1)\noverview = overview.sort_values(['Input Tokens', 'Model', 'Concurrency'])\n\ndef _highlight_errors(row):\n if row['Errors'] > 0:\n return ['background-color: #ffdddd'] * len(row)\n return [''] * len(row)\n\noverview.style.apply(_highlight_errors, axis=1).format({'Error Rate (%)': '{:.1f}%'})" + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 ModelRun TypeInput TokensOutput TokensConcurrencyCompletedErrorsError Rate (%)
0EncryptedMulti Run (10x)390010011000.0%
6EncryptedMulti Run (10x)800010011000.0%
12EncryptedMulti Run (10x)1600010011000.0%
1EncryptedMulti Run (10x)390010033000.0%
7EncryptedMulti Run (10x)800010033000.0%
13EncryptedMulti Run (10x)1600010033000.0%
2EncryptedMulti Run (10x)390010055000.0%
8EncryptedMulti Run (10x)800010055000.0%
14EncryptedMulti Run (10x)1600010055000.0%
3EncryptedMulti Run (10x)390010087556.2%
9EncryptedMulti Run (10x)800010087733.8%
15EncryptedMulti Run (10x)16000100872810.0%
4EncryptedMulti Run (10x)390010016148127.5%
10EncryptedMulti Run (10x)8000100161362415.0%
5EncryptedMulti Run (10x)3900100322635717.8%
11EncryptedMulti Run (10x)8000100322566420.0%
16Non-EncryptedMulti Run (10x)390010011000.0%
22Non-EncryptedMulti Run (10x)800010011000.0%
28Non-EncryptedMulti Run (10x)1600010011000.0%
17Non-EncryptedMulti Run (10x)390010033000.0%
23Non-EncryptedMulti Run (10x)800010033000.0%
29Non-EncryptedMulti Run (10x)1600010033000.0%
18Non-EncryptedMulti Run (10x)390010055000.0%
24Non-EncryptedMulti Run (10x)800010055000.0%
30Non-EncryptedMulti Run (10x)1600010055000.0%
19Non-EncryptedMulti Run (10x)390010088000.0%
25Non-EncryptedMulti Run (10x)800010088000.0%
31Non-EncryptedMulti Run (10x)1600010088000.0%
20Non-EncryptedMulti Run (10x)39001001616000.0%
26Non-EncryptedMulti Run (10x)80001001616000.0%
21Non-EncryptedMulti Run (10x)39001003232000.0%
27Non-EncryptedMulti Run (10x)80001003232000.0%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cols = ['label', \n", + " 'run_type', \n", + " 'num_input_tokens',\n", + " 'num_output_tokens', \n", + " 'num_concurrent_requests',\n", + " 'num_completed_requests', \n", + " 'number_errors', \n", + " 'error_rate_pct'\n", + " ]\n", + "overview = df_all[cols].copy()\n", + "overview.columns = ['Model', \n", + " 'Run Type', \n", + " 'Input Tokens',\n", + " 'Output Tokens', \n", + " 'Concurrency',\n", + " 'Completed', \n", + " 'Errors', \n", + " 'Error Rate (%)'\n", + " ]\n", + "overview['Error Rate (%)'] = overview['Error Rate (%)'].fillna(0).round(1)\n", + "overview = overview.sort_values(['Run Type', 'Model', 'Output Tokens', 'Concurrency'])\n", + "\n", + "def _highlight_errors(row):\n", + " if row['Errors'] > 0:\n", + " return ['background-color: #ffdddd'] * len(row)\n", + " return [''] * len(row)\n", + "\n", + "overview.style.apply(_highlight_errors, axis=1).format({'Error Rate (%)': '{:.1f}%'})" + ] }, { "cell_type": "markdown", @@ -52,87 +695,9816 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, + "id": "0722796c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Unnamed: 0', 'name', 'model', 'num_input_tokens', 'num_output_tokens',\n", + " 'num_concurrent_requests', 'server_ttft_s_min', 'server_ttft_s_mean',\n", + " 'server_ttft_s_p50', 'server_ttft_s_max',\n", + " 'server_end_to_end_latency_s_min', 'server_end_to_end_latency_s_mean',\n", + " 'server_end_to_end_latency_s_p50', 'server_end_to_end_latency_s_max',\n", + " 'server_output_token_per_s_min', 'server_output_token_per_s_mean',\n", + " 'server_output_token_per_s_p50', 'server_output_token_per_s_max',\n", + " 'acceptance_rate_min', 'acceptance_rate_p50', 'acceptance_rate_max',\n", + " 'server_number_input_tokens_p50', 'server_number_output_tokens_p50',\n", + " 'client_ttft_s_min', 'client_ttft_s_mean', 'client_ttft_s_p50',\n", + " 'client_ttft_s_max', 'client_end_to_end_latency_s_min',\n", + " 'client_end_to_end_latency_s_mean', 'client_end_to_end_latency_s_p50',\n", + " 'client_end_to_end_latency_s_max', 'client_output_token_per_s_min',\n", + " 'client_output_token_per_s_mean', 'client_output_token_per_s_p50',\n", + " 'client_output_token_per_s_max', 'client_total_output_throughput',\n", + " 'num_requests_started', 'num_completed_requests',\n", + " 'num_completed_requests_per_min', 'number_errors',\n", + " 'error_code_frequency', 'switching_time',\n", + " 'request_batching_frequencies', 'representative_batch_size',\n", + " 'total_encryption_time_ms_min', 'total_encryption_time_ms_mean',\n", + " 'total_encryption_time_ms_max', 'total_decryption_time_ms_min',\n", + " 'total_decryption_time_ms_mean', 'total_decryption_time_ms_max',\n", + " 'server_network_latency_ms_min', 'server_network_latency_ms_mean',\n", + " 'server_network_latency_ms_max', 'dataset_key', 'encrypted', 'run_type',\n", + " 'label', 'out_tokens_label', 'in_tokens_label', 'total_requests',\n", + " 'error_rate_pct', 'completion_rate_pct'],\n", + " dtype='object')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df_all.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 7, "id": "cell-errors-chart", "metadata": {}, - "outputs": [], - "source": "fig = px.bar(\n df_all,\n x='num_concurrent_requests',\n y='error_rate_pct',\n color='label',\n facet_col='in_tokens_label',\n barmode='group',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'error_rate_pct': 'Error Rate (%)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Request Error Rate by Concurrency — faceted by Input Tokens
'\n 'Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). '\n 'Non-Encrypted should be 0% throughout.'\n ),\n)\nfig.update_layout(height=420, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGUAAAAAAAAAeQAAAAAAA0DFA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkAAAAAAAAAuQAAAAAAAADRA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B", + "pattern": { + "shape": "" + } + }, + "name": "Encrypted", + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJEA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "alignmentgroup": "True", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency=%{x}
Error Rate (%)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA", + "pattern": { + "shape": "" + } + }, + "name": "Non-Encrypted", + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "group", + "height": 600, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Request Error Rate by Concurrency
Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). Non-Encrypted should be 0% throughout." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.3133333333333333 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "categoryarray": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis3": { + "anchor": "y3", + "categoryarray": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0, + 0.3133333333333333 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "xaxis5": { + "anchor": "y5", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "xaxis6": { + "anchor": "y6", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Error Rate (%)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 0.485 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Error Rate (%)" + } + }, + "yaxis5": { + "anchor": "x5", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis6": { + "anchor": "x6", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.bar(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='error_rate_pct',\n", + " color='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='group',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'error_rate_pct': 'Error Rate (%)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Request Error Rate by Concurrency
'\n", + " 'Errors appear on Encrypted model at concurrency > 8 (TEE queue saturation). '\n", + " 'Non-Encrypted should be 0% throughout.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=600, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "cell-reqmin-chart", "metadata": {}, - "outputs": [], - "source": "# Completed requests per minute — real system throughput capacity\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='num_completed_requests_per_min',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'num_completed_requests_per_min': 'Completed Requests / min',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'System Throughput: Completed Requests per Minute — faceted by Input Tokens
'\n 'Indicator of system capacity. '\n 'Encrypted throughput is increasingly limited by TEE queueing as input tokens grow '\n '(more bytes to encrypt) and at higher concurrencies.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "07zjFB2FXkCjkjoBTRhsQFg5tMh2/j5ADwu1pnl3P0DXEvJBz/Y/QM3MzMzMPD5A", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "xEKtad6NV0BB8WPMXWtFQOwvuycPqz5AO99PjZcuPkAOLbKd7wc7QL3jFB3J1TpA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "kDF3LSEPSkAPnDOitFtTQHZxGw3g7T9AkKD4MeauOkA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "7uvAOSMSWkD+Q/rt6yN0QCL99nXgSndAVHQkl/+veUBhw9MrZYt9QE7RkVz+RoNA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "XW3F/rILYEBQ/Bhz1yhjQOm3rwPnAmtAuycPC7XUakDY8PRKWWhqQDxO0ZFc1HBA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Completed Requests / min=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "fT81XrpRT0D0/dR46UZSQBrAWyBBdV5Ai/1l9+TDaUA=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "System Throughput: Completed Requests per Minute
ndicator of system capacity. Encrypted model throughput is severely limited by TEE queueing at higher concurrencies." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Completed Requests / min" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Completed requests per minute — real system throughput capacity\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='num_completed_requests_per_min',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'num_completed_requests_per_min': 'Completed Requests / min',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'System Throughput: Completed Requests per Minute
'\n", + " 'ndicator of system capacity. '\n", + " 'Encrypted model throughput is severely limited by TEE queueing at higher concurrencies.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "markdown", "id": "cell-server-hdr", "metadata": {}, - "source": "## 3. Server-Side Metrics — Behavior Across Input Sizes\n\nServer-side metrics measure what happens **inside the SambaNova engine**, after the TEE has\nrelayed the request. They tell us whether the TEE itself slows the model — and they isolate\nthe **input-size effect** on prefill vs. decode.\n\n**What to look for as input tokens grow (3,900 → 8,000 → 16,000):**\n- **Server TTFT** rises (prefill scales with input length)\n- **Server tok/s** for decode should be roughly stable (decode rate is mostly independent\n of input length once prefill is done)\n- **Server E2E latency** rises mainly because of prefill, not because of the TEE\n\n**TEE de-batching effect:** because the TEE processes encryption sequentially per core,\nconcurrent requests reach the inference server staggered. This often keeps the encrypted path's\n**effective server batch size smaller**, so its server-side TTFT can be lower than the\nnon-encrypted path at high concurrency." + "source": [ + "## 3. Server-Side Metrics — Assumption Validation ✅\n", + "\n", + "With both endpoints on equivalent configurations, server-side metrics now confirm the core assumption:\n", + "**the TEE does not affect inference speed inside the SambaNova engine.**\n", + "\n", + "**Server tok/s — endpoints are now matched:**\n", + "- Both endpoints baseline at ~585–620 tok/s (ratio 1.02–1.06× at concurrency 1–2 and 8+)\n", + "- A small anomaly remains at concurrency 4 (ratio ~1.33–1.46×) which may be a transient batching artifact\n", + "- The previous 1.87× gap was an endpoint configuration issue, now resolved\n", + "\n", + "**Server TTFT — two distinct regimes clearly visible:**\n", + "- **Concurrency 1–4**: Both models show nearly identical server TTFT (~0.091 s and ~0.161 s respectively)\n", + " — direct confirmation that the TEE has no impact on server prefill latency\n", + "- **Concurrency 8–32**: Encrypted stays flat at ~0.163 s; non-encrypted jumps to ~0.311 s.\n", + " This divergence is the **TEE de-batching effect** in action: because the TEE processes\n", + " requests sequentially per core, they arrive at the server staggered rather than simultaneously,\n", + " keeping the effective server batch smaller and prefill latency lower for the encrypted path.\n", + "\n", + "**Interesting consequence at high concurrency:** The encrypted model's server-side advantage from\n", + "de-batching (lower TTFT) can exceed the TEE network overhead, making encrypted client TTFT\n", + "actually lower than non-encrypted at concurrency ≥ 16 for 100-token responses (see Section 5)." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "cell-server-ttft", "metadata": {}, - "outputs": [], - "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_ttft_s_p50': 'Server TTFT p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server Time to First Token — p50 (faceted by Input Tokens)
'\n 'TTFT grows with input size (longer prefill). Watch for the de-batching effect: '\n 'at high concurrency, encrypted server TTFT can be lower than non-encrypted because '\n 'staggered TEE arrivals shrink the effective server batch.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "LGUZ4lgXtz851sVtNIC3PzSitDf4wsQ/0SLb+X5q1D8hsHJoke3EP3sUrkfhetQ/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "W7G/7J48zD+OBvAWSFDMP5vmHafoSNo/dy0hH/Rs2j9Cz2bV52rpP2Dl0CLb+fg/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "M8SxLm6j4z/35GGh1jT1P/p+arx0k+Q/FvvL7snD5D8=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "Z9Xnaiv2tz/caABvgQTFP/p+arx0k9Q/9UpZhjjW4z+tad5xio7zP4cW2c73U/U/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "Ns07TtGRzD9MpgpGJXXaPygPC7Wmeek/veMUHcnl+D+QoPgx5q4IQEcDeAskqAhA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "s+pztRX74z+yne+nxkv1Px+F61G4HuU/TfOOU3Qk8z8=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server Time to First Token — p50
Concurrency 1–4: nearly identical for both models ✅ — confirms TEE has no server-side impact. Concurrency 8–32: encrypted stays flat (~0.163 s), non-encrypted rises to ~0.311 s. This split is the TEE de-batching effect: staggered arrival keeps the effective server batch smaller for the encrypted path, reducing prefill queue time." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Server TTFT p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='server_ttft_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_ttft_s_p50': 'Server TTFT p50 (s)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Server Time to First Token — p50
'\n", + " 'Concurrency 1–4: nearly identical for both models ✅ — confirms TEE has no server-side impact. '\n", + " 'Concurrency 8–32: encrypted stays flat (~0.163 s), non-encrypted rises to ~0.311 s. '\n", + " 'This split is the TEE de-batching effect: staggered arrival keeps the effective server batch '\n", + " 'smaller for the encrypted path, reducing prefill queue time.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "cell-server-toks", "metadata": {}, - "outputs": [], - "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_output_token_per_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_output_token_per_s_p50': 'Server Output Tok/s p50 (per request)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server Output Throughput per Request — p50 (faceted by Input Tokens)
'\n 'Decode rate should be roughly independent of input size. Any large gap between '\n 'encrypted and non-encrypted in the same facet would point at endpoint configuration '\n 'differences, not the TEE itself.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ZmZmZuY1j0A5tMh2vmSMQNcS8kFPfYlAkst/SD/Oh0BkzF1LSLOHQPMf0m9fpodA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "rfpcbUWsiUC1N/jCZJyJQDtwzojSWIhAEhQ/xtwtiEB3LSEf9Kl6QIV80LNZQHVA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "b4EExQ8mgUBj7lpCPqGAQKabxCAwoIdAtRX7y253gkA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "CfmgZzMjkUC4rwPnDJ+PQCNKe4Ov6ItAn82qz1UUhkD3deCcEaJ+QPfkYaHWunBA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "vjCZKphkjEBYObTIdryKQPmgZ7NqpodAE2HD06sxgEBQjZduErp0QDJ3LSEf/3RA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "WmQ7389rg0CxUGuad2+BQLRZ9bnaT4hA5fIf0m8Hg0A=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server Output Throughput per Request — p50
Both endpoints now matched (~585–620 tok/s). Small gap at conc=4 may be a batching artifact. Encrypted stays flat across all concurrencies (TEE de-batching keeps effective server batch small). Non-Encrypted baseline is slightly higher but both degrade similarly at large batches." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Server Output Tok/s p50 (per request)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='server_output_token_per_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_output_token_per_s_p50': 'Server Output Tok/s p50 (per request)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Server Output Throughput per Request — p50
'\n", + " 'Both endpoints now matched (~585–620 tok/s). Small gap at conc=4 may be a batching artifact. '\n", + " 'Encrypted stays flat across all concurrencies (TEE de-batching keeps effective server batch small). '\n", + " 'Non-Encrypted baseline is slightly higher but both degrade similarly at large batches.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "cell-server-e2e", "metadata": {}, - "outputs": [], - "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='server_end_to_end_latency_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_end_to_end_latency_s_p50': 'Server E2E Latency p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title='Server End-to-End Latency — p50 (faceted by Input Tokens)',\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "Qxzr4jYayD/NO07RkVzGP2lv8IXJVNE/UI2XbhKD1D9xPQrXo3DRP+C+DpwzotQ/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "8rBQa5p3zD/3deCcEaXVP7N78rBQa9o/lPYGX5hM4T8pXI/C9SjuP2b35GGh1vo/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "3bWEfNCz4z95WKg1zTv1P/RsVn2utug/V+wvuycP6T8=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "0gDeAgmKxz+8BRIUP8bQP/tcbcX+sts/NBE2PL1S6D9EaW/whcn2Pw5Pr5RliPY/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "gy9MpgpG1T8DCYofY+7gP78OnDOitO0/9ihcj8L1+z/BqKROQBMLQEmdgCbCBgtA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Server E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "aLPqc7UV6T/67evAOSP4P9k9eVioNek/OpLLf0i/9T8=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server End-to-End Latency — p50" + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Server E2E Latency p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='server_end_to_end_latency_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_end_to_end_latency_s_p50': 'Server E2E Latency p50 (s)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title='Server End-to-End Latency — p50',\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "id": "cell-server-delta", "metadata": {}, - "outputs": [], - "source": "# Server metrics delta table — Encrypted minus Non-Encrypted (per Input Tokens × Concurrency)\nDIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\ndf_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n\nserver_metrics = [\n ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n ('server_end_to_end_latency_s_p50','Server E2E p50 (s)'),\n]\n\ndelta_rows = []\nfor col, label in server_metrics:\n if col not in df_enc_s.columns:\n continue\n for idx in df_enc_s.index:\n if idx not in df_plain_s.index:\n continue\n enc_val = df_enc_s.loc[idx, col]\n plain_val = df_plain_s.loc[idx, col]\n if pd.isna(enc_val) or pd.isna(plain_val):\n continue\n delta = enc_val - plain_val\n pct_chg = delta / plain_val * 100 if plain_val != 0 else np.nan\n delta_rows.append({\n 'Metric': label,\n 'Input Tokens': idx[0],\n 'Output Tokens': idx[1],\n 'Concurrency': idx[2],\n 'Non-Encrypted': plain_val,\n 'Encrypted': enc_val,\n 'Delta': delta,\n '% Change': pct_chg,\n })\n\ndf_server_delta = pd.DataFrame(delta_rows)\ndf_server_delta = df_server_delta.sort_values(['Metric', 'Input Tokens', 'Concurrency'])\n\ndef _pct_color(val):\n if pd.isna(val): return ''\n if val > 50: return 'background-color: #ffaaaa'\n if val > 20: return 'background-color: #ffd8aa'\n if val > 0: return 'background-color: #fffacc'\n if val < -20: return 'background-color: #aaffaa'\n return ''\n\ndf_server_delta.style \\\n .applymap(_pct_color, subset=['% Change']) \\\n .format({\n 'Non-Encrypted': '{:.4f}',\n 'Encrypted': '{:.4f}',\n 'Delta': '{:+.4f}',\n '% Change': '{:+.1f}%',\n })" + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 MetricRun TypeInput TokensConcurrencyNon-EncryptedEncryptedDelta% Change
32Server E2E p50 (s)Multi Run (10x)390010.18390.1883+0.0044+2.4%
33Server E2E p50 (s)Multi Run (10x)390030.26210.1747-0.0874-33.3%
34Server E2E p50 (s)Multi Run (10x)390050.43280.2708-0.1620-37.4%
35Server E2E p50 (s)Multi Run (10x)390080.76010.3205-0.4396-57.8%
36Server E2E p50 (s)Multi Run (10x)3900161.42420.2725-1.1517-80.9%
37Server E2E p50 (s)Multi Run (10x)3900321.40830.3224-1.0859-77.1%
38Server E2E p50 (s)Multi Run (10x)800010.33240.2224-0.1100-33.1%
39Server E2E p50 (s)Multi Run (10x)800030.52910.3382-0.1909-36.1%
40Server E2E p50 (s)Multi Run (10x)800050.92830.4128-0.5155-55.5%
41Server E2E p50 (s)Multi Run (10x)800081.74750.5406-1.2069-69.1%
42Server E2E p50 (s)Multi Run (10x)8000163.38440.9425-2.4419-72.2%
43Server E2E p50 (s)Multi Run (10x)8000323.37831.6774-1.7009-50.3%
44Server E2E p50 (s)Multi Run (10x)1600010.78390.6157-0.1682-21.5%
45Server E2E p50 (s)Multi Run (10x)1600031.50861.3271-0.1815-12.0%
46Server E2E p50 (s)Multi Run (10x)1600050.78780.7723-0.0155-2.0%
47Server E2E p50 (s)Multi Run (10x)1600081.35920.7831-0.5761-42.4%
0Server TTFT p50 (s)Multi Run (10x)390010.09360.0902-0.0034-3.6%
1Server TTFT p50 (s)Multi Run (10x)390030.16420.0918-0.0724-44.1%
2Server TTFT p50 (s)Multi Run (10x)390050.32150.1622-0.1593-49.5%
3Server TTFT p50 (s)Multi Run (10x)390080.61990.3190-0.3009-48.5%
4Server TTFT p50 (s)Multi Run (10x)3900161.22230.1635-1.0588-86.6%
5Server TTFT p50 (s)Multi Run (10x)3900321.33300.3200-1.0130-76.0%
6Server TTFT p50 (s)Multi Run (10x)800010.22320.2206-0.0026-1.2%
7Server TTFT p50 (s)Multi Run (10x)800030.41340.2212-0.1922-46.5%
8Server TTFT p50 (s)Multi Run (10x)800050.79610.4107-0.3854-48.4%
9Server TTFT p50 (s)Multi Run (10x)800081.55610.4129-1.1432-73.5%
10Server TTFT p50 (s)Multi Run (10x)8000163.08540.7943-2.2911-74.3%
11Server TTFT p50 (s)Multi Run (10x)8000323.08211.5610-1.5211-49.4%
12Server TTFT p50 (s)Multi Run (10x)1600010.62440.6137-0.0107-1.7%
13Server TTFT p50 (s)Multi Run (10x)1600031.33101.3254-0.0056-0.4%
14Server TTFT p50 (s)Multi Run (10x)1600050.66000.6430-0.0170-2.6%
15Server TTFT p50 (s)Multi Run (10x)1600081.19640.6489-0.5475-45.8%
16Server Tok/s p50Multi Run (10x)390011096.8002998.7375-98.0627-8.9%
17Server Tok/s p50Multi Run (10x)390031011.8813908.5930-103.2883-10.2%
18Server Tok/s p50Multi Run (10x)39005893.0857815.6637-77.4220-8.7%
19Server Tok/s p50Multi Run (10x)39008706.5419761.7809+55.2390+7.8%
20Server Tok/s p50Multi Run (10x)390016490.1293758.4103+268.2810+54.7%
21Server Tok/s p50Multi Run (10x)390032267.6774756.7966+489.1192+182.7%
22Server Tok/s p50Multi Run (10x)80001908.5743821.5339-87.0404-9.6%
23Server Tok/s p50Multi Run (10x)80003855.5580819.5492-36.0088-4.2%
24Server Tok/s p50Multi Run (10x)80005756.8021779.1028+22.3007+2.9%
25Server Tok/s p50Multi Run (10x)80008518.2089773.7328+255.5239+49.3%
26Server Tok/s p50Multi Run (10x)800016331.6295426.6221+94.9926+28.6%
27Server Tok/s p50Multi Run (10x)800032335.9451340.0219+4.0768+1.2%
28Server Tok/s p50Multi Run (10x)160001621.4765548.7577-72.7188-11.7%
29Server Tok/s p50Multi Run (10x)160003557.9334532.1554-25.7780-4.6%
30Server Tok/s p50Multi Run (10x)160005777.9818756.0235-21.9583-2.8%
31Server Tok/s p50Multi Run (10x)160008608.9296590.9291-18.0005-3.0%
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Server metrics delta table — Encrypted minus Non-Encrypted\n", + "DIMS = ['run_type', 'num_input_tokens', 'num_concurrent_requests']\n", + "\n", + "df_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\n", + "df_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n", + "\n", + "server_metrics = [\n", + " ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n", + " ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n", + " ('server_end_to_end_latency_s_p50','Server E2E p50 (s)'),\n", + "]\n", + "\n", + "delta_rows = []\n", + "for col, label in server_metrics:\n", + " if col not in df_enc_s.columns:\n", + " continue\n", + " for idx in df_enc_s.index:\n", + " if idx not in df_plain_s.index:\n", + " continue\n", + " enc_val = df_enc_s.loc[idx, col]\n", + " plain_val = df_plain_s.loc[idx, col]\n", + " if pd.isna(enc_val) or pd.isna(plain_val):\n", + " continue\n", + " delta = enc_val - plain_val\n", + " pct_chg = delta / plain_val * 100 if plain_val != 0 else np.nan\n", + " delta_rows.append({\n", + " 'Metric': label,\n", + " 'Run Type': idx[0],\n", + " 'Input Tokens': idx[1],\n", + " 'Concurrency': idx[2],\n", + " 'Non-Encrypted': plain_val,\n", + " 'Encrypted': enc_val,\n", + " 'Delta': delta,\n", + " '% Change': pct_chg,\n", + " })\n", + "\n", + "df_server_delta = pd.DataFrame(delta_rows)\n", + "df_server_delta = df_server_delta.sort_values(['Metric', 'Run Type', 'Input Tokens', 'Concurrency'])\n", + "\n", + "def _pct_color(val):\n", + " if pd.isna(val): return ''\n", + " if val > 50: return 'background-color: #ffaaaa'\n", + " if val > 20: return 'background-color: #ffd8aa'\n", + " if val > 0: return 'background-color: #fffacc'\n", + " if val < -20: return 'background-color: #aaffaa'\n", + " return ''\n", + "\n", + "df_server_delta.style \\\n", + " .applymap(_pct_color, subset=['% Change']) \\\n", + " .format({\n", + " 'Non-Encrypted': '{:.4f}',\n", + " 'Encrypted': '{:.4f}',\n", + " 'Delta': '{:+.4f}',\n", + " '% Change': '{:+.1f}%',\n", + " })" + ] }, { "cell_type": "markdown", "id": "cell-tee-hdr", "metadata": {}, - "source": "## 4. TEE Overhead Decomposition (Encrypted Model Only)\n\nThree measurable components are returned by the TEE per request:\n\n| Component | Description | Expected Behavior vs Input Tokens |\n|-----------|-------------|----------------------------------|\n| **Input Encryption** | Time to encrypt the prompt before sending to server | grows with input token count |\n| **Output Decryption** | Cumulative time to decrypt all streaming output chunks | ~constant (output is fixed at 100) |\n| **Network Hop** | Round-trip latency through the TEE (Client→TEE→Server→TEE→Client) | grows with concurrency (TEE queue) and payload size |\n\n> Faceting by input tokens lets us see how much of the TEE overhead is driven by **prompt size**\n> as opposed to concurrency." + "source": [ + "## 4. TEE Overhead Decomposition (Encrypted Model Only)\n", + "\n", + "Three measurable components are returned by the TEE per request:\n", + "\n", + "| Component | Description | Expected Behavior |\n", + "|-----------|-------------|-------------------|\n", + "| **Input Encryption** | Time to encrypt the prompt before sending to server | ~constant, independent of output length |\n", + "| **Output Decryption** | Cumulative time to decrypt all streaming output chunks | grows with output token count |\n", + "| **Network Hop** | Round-trip latency through the TEE (Client→TEE→Server→TEE→Client) | grows with concurrency (TEE queue) and output tokens |\n", + "\n", + "> The network hop is the dominant overhead. At high concurrency it grows due to TEE core saturation." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "id": "cell-tee-stack", "metadata": {}, - "outputs": [], - "source": "df_tee = df_all[df_all['label'] == 'Encrypted'].copy()\n\n# Convert ms → s for consistent units with latency charts\ndf_tee['Network Hop'] = df_tee['server_network_latency_ms_mean'] / 1000\ndf_tee['Input Encryption'] = df_tee['total_encryption_time_ms_mean'] / 1000\ndf_tee['Output Decryption'] = df_tee['total_decryption_time_ms_mean'] / 1000\n\nTEE_ID_COLS = ['in_tokens_label', 'num_concurrent_requests']\nTEE_VAL_COLS = ['Network Hop', 'Input Encryption', 'Output Decryption']\n\ndf_tee_melt = df_tee[TEE_ID_COLS + TEE_VAL_COLS].melt(\n id_vars=TEE_ID_COLS, var_name='Component', value_name='Overhead (s)'\n)\n\nCOMP_COLORS = {\n 'Network Hop': '#FF7F0E',\n 'Input Encryption': '#D62728',\n 'Output Decryption': '#2CA02C',\n}\n\nfig = px.bar(\n df_tee_melt,\n x='num_concurrent_requests',\n y='Overhead (s)',\n color='Component',\n facet_col='in_tokens_label',\n barmode='stack',\n color_discrete_map=COMP_COLORS,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'TEE Overhead Breakdown per Request — faceted by Input Tokens
'\n 'Network Hop dominates. Encryption grows with input size (more bytes to encrypt). '\n 'Decryption is roughly constant since output tokens are fixed at 100.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Component=Network Hop
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAgAQMFCBAgAQMFCA==", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "aO9CKRAs1T/iqrLviiDiP5pyzwTUJeM/YAsw4vHj5D9cVfZdETzrP0vvdhjuN/E/bAw6IXRQ2z/7E6Y5w57pPz4KMl3jLvE/jJ5b6EpE+T8YZZGBlzQDQDJOjeH7HAtAwT+lSpQ97T+L/tDMkysAQGowaHy6lfc/EZ/gB4y6+z8=", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Input Encryption
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAgAQMFCBAgAQMFCA==", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ynISSl8IiT875wLygA2DPyJOzB94IYI/KhHyi1yBgj91xMZh1cWCP9R+aydKQoI/f0ulRLcDkj+wK3ewD/yRP+86G/LPDJI/MtOsIpLXkT+lcV5Sa1CSP86XzdIEQJM/3ydYLfpUoz/LMh9rob+jP09FhUWgVaE/4kJ5egDmoT8=", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Output Decryption
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQMFCBAgAQMFCBAgAQMFCA==", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "WsnYGlsZXj8gYRiw5CpGP+dSXFX2XUE/EkO8v4sIQD8BO5ImObtAP25De6tktjo/3iRhOgiVMz8fDUwTW+Y5P7lyUYjb/Do/22SepuA6QD8x5lNscTI2P+nELwYg/zY/zFE2m33UNT88G6hC8oQ0P4SVr3A3LT0/rWcIxyx7Qj8=", + "dtype": "f8" + }, + "yaxis": "y" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "stack", + "height": 700, + "legend": { + "title": { + "text": "Component" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Overhead Breakdown per Request (Encrypted Model Only)
Network Hop dominates. Encryption is near-constant. Decryption scales with output token count (streaming per-chunk decryption)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.98 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Overhead (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Overhead (s)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_tee = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "\n", + "# Convert ms → s for consistent units with latency charts\n", + "df_tee['Network Hop'] = df_tee['server_network_latency_ms_mean'] / 1000\n", + "df_tee['Input Encryption'] = df_tee['total_encryption_time_ms_mean'] / 1000\n", + "df_tee['Output Decryption'] = df_tee['total_decryption_time_ms_mean'] / 1000\n", + "\n", + "TEE_ID_COLS = ['run_type', 'out_tokens_label', 'num_concurrent_requests']\n", + "TEE_VAL_COLS = ['Network Hop', 'Input Encryption', 'Output Decryption']\n", + "\n", + "df_tee_melt = df_tee[TEE_ID_COLS + TEE_VAL_COLS].melt(\n", + " id_vars=TEE_ID_COLS, var_name='Component', value_name='Overhead (s)'\n", + ")\n", + "\n", + "COMP_COLORS = {\n", + " 'Network Hop': '#FF7F0E',\n", + " 'Input Encryption': '#D62728',\n", + " 'Output Decryption': '#2CA02C',\n", + "}\n", + "\n", + "fig = px.bar(\n", + " df_tee_melt,\n", + " x='num_concurrent_requests',\n", + " y='Overhead (s)',\n", + " color='Component',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='stack',\n", + " color_discrete_map=COMP_COLORS,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'run_type': 'Run Type',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " },\n", + " title=(\n", + " 'TEE Overhead Breakdown per Request (Encrypted Model Only)
'\n", + " 'Network Hop dominates. Encryption is near-constant. '\n", + " 'Decryption scales with output token count (streaming per-chunk decryption).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "id": "cell-network-latency", "metadata": {}, - "outputs": [], - "source": "# Network latency growth — most important overhead component\nfig = px.line(\n df_tee,\n x='num_concurrent_requests',\n y='server_network_latency_ms_mean',\n color='in_tokens_label',\n facet_col='in_tokens_label',\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'server_network_latency_ms_mean': 'TEE Network Latency — Mean (ms)',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'TEE Network Latency vs Concurrency — faceted by Input Tokens
'\n 'Grows with concurrency (TEE queueing) AND with input tokens '\n '(larger encrypted payload to ship).'\n ),\n)\nfig.update_layout(height=420, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Input Tokens=3900 input tokens
Run Type=Multi Run (10x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "3900 input tokens, Multi Run (10x)", + "line": { + "color": "#636efa", + "dash": "dash" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "3900 input tokens, Multi Run (10x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "zF1LyAetdEDhehSux7OBQOqVsgzxsoJAHOviNppmhEBcj8L1qJiKQK8l5IOe0JBA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Input Tokens=8000 input tokens
Run Type=Multi Run (10x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "8000 input tokens, Multi Run (10x)", + "line": { + "color": "#EF553B", + "dash": "dash" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "8000 input tokens, Multi Run (10x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "IbByaJGsekCDL0ymCgWJQAHeAgnKx5BA1XjpJrGsmEC5/If0W8GiQF3+Q/pNeqpA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Input Tokens=16000 input tokens
Run Type=Multi Run (10x)
Concurrency (log scale)=%{x}
TEE Network Latency — Mean (ms)=%{y}", + "legendgroup": "16000 input tokens, Multi Run (10x)", + "line": { + "color": "#00cc96", + "dash": "dash" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "16000 input tokens, Multi Run (10x)", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "QmDl0CKOjEAnMQisHJWfQEi/fR04CJdAV1uxvywUm0A=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15999999999999998, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49999999999999994, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8399999999999999, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 450, + "legend": { + "title": { + "text": "Input Tokens, Run Type" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Network Latency vs Concurrency
Solid = Single Run (1x) | Dashed = Multi Run (10x). Grows with concurrency (TEE queueing) AND with output tokens (streaming: each decrypted chunk adds a network round-trip)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.31999999999999995 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.33999999999999997, + 0.6599999999999999 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6799999999999999, + 0.9999999999999999 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "TEE Network Latency — Mean (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Network latency growth — most important overhead component\n", + "fig = px.line(\n", + " df_tee,\n", + " x='num_concurrent_requests',\n", + " y='server_network_latency_ms_mean',\n", + " color='in_tokens_label',\n", + " symbol='run_type',\n", + " line_dash='run_type',\n", + " line_dash_map={'Single Run (1x)': 'solid', 'Multi Run (10x)': 'dash'},\n", + " facet_col='in_tokens_label',\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'server_network_latency_ms_mean': 'TEE Network Latency — Mean (ms)',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'TEE Network Latency vs Concurrency
'\n", + " 'Solid = Single Run (1x) | Dashed = Multi Run (10x). '\n", + " 'Grows with concurrency (TEE queueing) AND with output tokens '\n", + " '(streaming: each decrypted chunk adds a network round-trip).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=450, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "cell-enc-dec-times", "metadata": {}, - "outputs": [], - "source": "# Encryption and decryption times detail — one line per Input Tokens\nfig = make_subplots(\n rows=1, cols=2,\n subplot_titles=['Input Encryption Time (ms)', 'Output Decryption Time (ms)'],\n)\n\n_input_colors = {3900: '#1f77b4', 8000: '#2ca02c', 16000: '#ff7f0e'}\n_shown = set()\n\nfor in_tok, color in _input_colors.items():\n sub = df_tee[df_tee['num_input_tokens'] == in_tok].sort_values('num_concurrent_requests')\n name = f'{in_tok:,} input tokens'\n show = name not in _shown\n kw = dict(x=sub['num_concurrent_requests'], mode='lines+markers',\n name=name, line=dict(color=color),\n legendgroup=name, showlegend=show)\n fig.add_trace(go.Scatter(y=sub['total_encryption_time_ms_mean'], **kw), row=1, col=1)\n kw['showlegend'] = False\n fig.add_trace(go.Scatter(y=sub['total_decryption_time_ms_mean'], **kw), row=1, col=2)\n _shown.add(name)\n\nfig.update_xaxes(\n type='log', tickvals=CONC_ORDER, ticktext=CONC_STR,\n title_text='Concurrency (log scale)',\n)\nfig.update_yaxes(title_text='Time (ms)', col=1)\nfig.update_yaxes(title_text='Time (ms)', col=2)\nfig.update_layout(\n height=420, width=1200, template='plotly_white',\n legend_title='Input Tokens',\n title=(\n 'TEE Encryption & Decryption Times — by Input Tokens
'\n 'Encryption scales with input size (more bytes per prompt). '\n 'Decryption is roughly flat across input sizes since output is fixed at 100 tokens.'\n ),\n)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "legendgroup": "3900 in | Single Run (1x)", + "line": { + "color": "#1f77b4", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "3900 in | Single Run (1x)", + "showlegend": true, + "type": "scatter", + "x": [], + "xaxis": "x", + "y": [], + "yaxis": "y" + }, + { + "legendgroup": "3900 in | Single Run (1x)", + "line": { + "color": "#1f77b4", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "3900 in | Single Run (1x)", + "showlegend": false, + "type": "scatter", + "x": [], + "xaxis": "x2", + "y": [], + "yaxis": "y2" + }, + { + "legendgroup": "8000 in | Single Run (1x)", + "line": { + "color": "#ff7f0e", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "8000 in | Single Run (1x)", + "showlegend": true, + "type": "scatter", + "x": [], + "xaxis": "x", + "y": [], + "yaxis": "y" + }, + { + "legendgroup": "8000 in | Single Run (1x)", + "line": { + "color": "#ff7f0e", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "8000 in | Single Run (1x)", + "showlegend": false, + "type": "scatter", + "x": [], + "xaxis": "x2", + "y": [], + "yaxis": "y2" + }, + { + "legendgroup": "16000 in | Single Run (1x)", + "line": { + "color": "#2ca02c", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "16000 in | Single Run (1x)", + "showlegend": true, + "type": "scatter", + "x": [], + "xaxis": "x", + "y": [], + "yaxis": "y" + }, + { + "legendgroup": "16000 in | Single Run (1x)", + "line": { + "color": "#2ca02c", + "dash": "solid" + }, + "mode": "lines+markers", + "name": "16000 in | Single Run (1x)", + "showlegend": false, + "type": "scatter", + "x": [], + "xaxis": "x2", + "y": [], + "yaxis": "y2" + }, + { + "legendgroup": "3900 in | Multi Run (10x)", + "line": { + "color": "#1f77b4", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "3900 in | Multi Run (10x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "GQRWDi1yKEDQ1VbsL5siQE2EDU+vtCFAw2SqYFQSIkDaG3xhMlUiQNv5fmq81CFA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "3900 in | Multi Run (10x)", + "line": { + "color": "#1f77b4", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "3900 in | Multi Run (10x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "orQ3+MJk/T/ZzvdT46XlP/YoXI/C9eA//7J78rBQ3z+fzarP1VbgP9lfdk8eFto/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "legendgroup": "8000 in | Multi Run (10x)", + "line": { + "color": "#ff7f0e", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "8000 in | Multi Run (10x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "umsJ+aCXMUCqYFRSJ5AxQI2XbhKDoDFAP8bctYRsMUD7OnDOiOIxQD/G3LWEzDJA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "8000 in | Multi Run (10x)", + "line": { + "color": "#ff7f0e", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "8000 in | Multi Run (10x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "Ad4CCYof0z/QRNjw9ErZPwmKH2PuWto/+1xtxf6y3z/M7snDQq3VP0ymCkYlddY/", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "legendgroup": "16000 in | Multi Run (10x)", + "line": { + "color": "#2ca02c", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "16000 in | Multi Run (10x)", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "8BZIUPzgQkCad5yiI0lDQK8l5IOe7UBAUWuad5x6QUA=", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "legendgroup": "16000 in | Multi Run (10x)", + "line": { + "color": "#2ca02c", + "dash": "dash" + }, + "mode": "lines+markers", + "name": "16000 in | Multi Run (10x)", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "4QuTqYJR1T+ZKhiV1AnUPwN4CyQoftw/PzVeukkM4j8=", + "dtype": "f8" + }, + "yaxis": "y2" + } + ], + "layout": { + "annotations": [ + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Input Encryption Time (ms)", + "x": 0.225, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": { + "size": 16 + }, + "showarrow": false, + "text": "Output Decryption Time (ms)", + "x": 0.775, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 420, + "legend": { + "title": { + "text": "in tokens | run type" + } + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "TEE Encryption & Decryption Times
Encryption is near-constant (~4-10 ms). Decryption grows with output token count; decreases at higher concurrency as TEE queue pressure compresses per-request wall time." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.45 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.55, + 1 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Time (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Time (ms)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Encryption and decryption times detail\n", + "fig = make_subplots(\n", + " rows=1, cols=2,\n", + " subplot_titles=['Input Encryption Time (ms)', 'Output Decryption Time (ms)'],\n", + ")\n", + "\n", + "_run_styles = {'Single Run (1x)': 'solid', 'Multi Run (10x)': 'dash'}\n", + "_tok_colors = {3900: '#1f77b4', 8000: '#ff7f0e', 16000: '#2ca02c'}\n", + "_shown = set()\n", + "\n", + "for run_type, dash in _run_styles.items():\n", + " for in_tok, color in _tok_colors.items():\n", + " sub = df_tee[(df_tee['run_type'] == run_type) & (df_tee['num_input_tokens'] == in_tok)]\n", + " name = f'{in_tok} in | {run_type}'\n", + " show = name not in _shown\n", + " kw = dict(x=sub['num_concurrent_requests'], mode='lines+markers',\n", + " name=name, line=dict(color=color, dash=dash),\n", + " legendgroup=name, showlegend=show)\n", + " fig.add_trace(go.Scatter(y=sub['total_encryption_time_ms_mean'], **kw), row=1, col=1)\n", + " kw['showlegend'] = False\n", + " fig.add_trace(go.Scatter(y=sub['total_decryption_time_ms_mean'], **kw), row=1, col=2)\n", + " _shown.add(name)\n", + "\n", + "fig.update_xaxes(\n", + " type='log', tickvals=CONC_ORDER, ticktext=CONC_STR,\n", + " title_text='Concurrency (log scale)',\n", + ")\n", + "fig.update_yaxes(title_text='Time (ms)', col=1)\n", + "fig.update_yaxes(title_text='Time (ms)', col=2)\n", + "fig.update_layout(\n", + " height=420, width=1100, template='plotly_white',\n", + " legend_title='in tokens | run type',\n", + " title=(\n", + " 'TEE Encryption & Decryption Times
'\n", + " 'Encryption is near-constant (~4-10 ms). '\n", + " 'Decryption grows with output token count; decreases at higher concurrency '\n", + " 'as TEE queue pressure compresses per-request wall time.'\n", + " ),\n", + ")\n", + "fig.show()" + ] }, { "cell_type": "markdown", @@ -149,81 +10521,15776 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "cell-client-ttft", "metadata": {}, - "outputs": [], - "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_ttft_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_ttft_s_p50': 'Client TTFT p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client Time to First Token — p50 (faceted by Input Tokens)
'\n 'Both models slow down as input grows (longer prefill). '\n 'Encrypted carries TEE network + encryption overhead on top — gap typically widens '\n 'with concurrency, but de-batching can flip it at high concurrency on smaller prompts.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "fT81XrpJ2D8tIR/0bFbdP6vP1VbsL+c/5/up8dJN7D+Hp1fKMsT1Pxb7y+7Jw/8/", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "TDeJQWDl4j+n6Egu/yHrP1K4HoXrUfs/OGdEaW9wBECX/5B++zoHQGq8dJMYhBJA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "ldQJaCJs8T+utmJ/2T0BQDnWxW00gP0/1sVtNIA3AUA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "9dvXgXNG0D8eFmpN847bP+58PzVeuuU/SZ2AJsKG7z+Zu5aQD3r8P/7UeOkmMQdA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "Ke0NvjCZ1j8Zc9cS8kHrP0Rpb/CFyfM/coqO5PIfAEAhsHJokW0OQN21hHzQ8xpA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client TTFT p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "2/l+arx06T+oV8oyxDECQBZqTfOOUwJA6SYxCKwcAUA=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client Time to First Token — p50
At concurrency 1–8: encrypted is slower due to TEE network overhead. At concurrency ≥ 16 (100 tokens): encrypted TTFT drops below non-encrypted — the TEE de-batching advantage on the server (lower prefill time) outweighs the network overhead, flipping the comparison. This crossover does not appear for 1,024 tokens where network overhead is larger and dominates." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Client TTFT p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_ttft_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_ttft_s_p50': 'Client TTFT p50 (s)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client Time to First Token — p50
'\n", + " 'At concurrency 1–8: encrypted is slower due to TEE network overhead. '\n", + " 'At concurrency ≥ 16 (100 tokens): encrypted TTFT drops below non-encrypted — '\n", + " 'the TEE de-batching advantage on the server (lower prefill time) outweighs '\n", + " 'the network overhead, flipping the comparison. This crossover does not appear '\n", + " 'for 1,024 tokens where network overhead is larger and dominates.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "cell-ttft-attribution", "metadata": {}, - "outputs": [], - "source": "# Client TTFT overhead attribution: stacked TEE components vs total delta\nDIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_enc_a = df_all[df_all['label'] == 'Encrypted'].copy()\ndf_plain_a = df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n columns={'client_ttft_s_p50': 'client_ttft_plain'}\n)\ndf_attr = df_enc_a.merge(df_plain_a, on=DIMS)\n\ndf_attr['client_ttft_delta'] = df_attr['client_ttft_s_p50'] - df_attr['client_ttft_plain']\ndf_attr['Network Hop (s)'] = df_attr['server_network_latency_ms_mean'] / 1000\ndf_attr['Input Encryption (s)'] = df_attr['total_encryption_time_ms_mean'] / 1000\ndf_attr['Output Decryption (s)']= df_attr['total_decryption_time_ms_mean'] / 1000\ndf_attr['Residual (s)'] = (\n df_attr['client_ttft_delta']\n - df_attr['Network Hop (s)']\n - df_attr['Input Encryption (s)']\n - df_attr['Output Decryption (s)']\n).clip(lower=0)\n\nATTR_COLS = ['Network Hop (s)', 'Input Encryption (s)', 'Output Decryption (s)', 'Residual (s)']\nATTR_COLORS = {\n 'Network Hop (s)': '#FF7F0E',\n 'Input Encryption (s)': '#D62728',\n 'Output Decryption (s)': '#2CA02C',\n 'Residual (s)': '#9467BD',\n}\n\ndf_attr_melt = df_attr.melt(\n id_vars=['in_tokens_label', 'num_concurrent_requests', 'client_ttft_delta'],\n value_vars=ATTR_COLS, var_name='Component', value_name='Overhead (s)',\n).dropna(subset=['Overhead (s)'])\n\nfig = px.bar(\n df_attr_melt,\n x='num_concurrent_requests',\n y='Overhead (s)',\n color='Component',\n facet_col='in_tokens_label',\n barmode='stack',\n color_discrete_map=ATTR_COLORS,\n category_orders={\n 'num_concurrent_requests': CONC_ORDER,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'num_concurrent_requests': 'Concurrency',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta — by Input Tokens
'\n 'Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. '\n 'Residual = delta not fully explained by TEE metrics (measurement noise / endpoint diff).'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(type='category')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Component=Network Hop (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Network Hop (s)", + "marker": { + "color": "#FF7F0E", + "pattern": { + "shape": "" + } + }, + "name": "Network Hop (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQEBAQEBAQEBAwMDAwMDAwMDBQUFBQUFBQUFCAgICAgICAgIEBAQECAgICA=", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "aO9CKRAs1T9o70IpECzVP2jvQikQLNU/bAw6IXRQ2z9sDDohdFDbP2wMOiF0UNs/wT+lSpQ97T/BP6VKlD3tP8E/pUqUPe0/4qqy74og4j/iqrLviiDiP+Kqsu+KIOI/+xOmOcOe6T/7E6Y5w57pP/sTpjnDnuk/i/7QzJMrAECL/tDMkysAQIv+0MyTKwBAmnLPBNQl4z+acs8E1CXjP5pyzwTUJeM/PgoyXeMu8T8+CjJd4y7xPz4KMl3jLvE/ajBofLqV9z9qMGh8upX3P2owaHy6lfc/YAsw4vHj5D9gCzDi8ePkP2ALMOLx4+Q/jJ5b6EpE+T+MnlvoSkT5P4yeW+hKRPk/EZ/gB4y6+z8Rn+AHjLr7PxGf4AeMuvs/XFX2XRE86z9cVfZdETzrPxhlkYGXNANAGGWRgZc0A0BL73YY7jfxP0vvdhjuN/E/Mk6N4fscC0AyTo3h+xwLQA==", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Input Encryption (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Input Encryption (s)", + "marker": { + "color": "#D62728", + "pattern": { + "shape": "" + } + }, + "name": "Input Encryption (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQEBAQEBAQEBAwMDAwMDAwMDBQUFBQUFBQUFCAgICAgICAgIEBAQECAgICA=", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ynISSl8IiT/KchJKXwiJP8pyEkpfCIk/f0ulRLcDkj9/S6VEtwOSP39LpUS3A5I/3ydYLfpUoz/fJ1gt+lSjP98nWC36VKM/O+cC8oANgz875wLygA2DPzvnAvKADYM/sCt3sA/8kT+wK3ewD/yRP7Ard7AP/JE/yzIfa6G/oz/LMh9rob+jP8syH2uhv6M/Ik7MH3ghgj8iTswfeCGCPyJOzB94IYI/7zob8s8Mkj/vOhvyzwySP+86G/LPDJI/T0WFRaBVoT9PRYVFoFWhP09FhUWgVaE/KhHyi1yBgj8qEfKLXIGCPyoR8otcgYI/MtOsIpLXkT8y06wikteRPzLTrCKS15E/4kJ5egDmoT/iQnl6AOahP+JCeXoA5qE/dcTGYdXFgj91xMZh1cWCP6VxXlJrUJI/pXFeUmtQkj/UfmsnSkKCP9R+aydKQoI/zpfN0gRAkz/Ol83SBECTPw==", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Output Decryption (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Output Decryption (s)", + "marker": { + "color": "#2CA02C", + "pattern": { + "shape": "" + } + }, + "name": "Output Decryption (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQEBAQEBAQEBAwMDAwMDAwMDBQUFBQUFBQUFCAgICAgICAgIEBAQECAgICA=", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "WsnYGlsZXj9aydgaWxleP1rJ2BpbGV4/3iRhOgiVMz/eJGE6CJUzP94kYToIlTM/zFE2m33UNT/MUTabfdQ1P8xRNpt91DU/IGEYsOQqRj8gYRiw5CpGPyBhGLDkKkY/Hw1ME1vmOT8fDUwTW+Y5Px8NTBNb5jk/PBuoQvKEND88G6hC8oQ0PzwbqELyhDQ/51JcVfZdQT/nUlxV9l1BP+dSXFX2XUE/uXJRiNv8Oj+5clGI2/w6P7lyUYjb/Do/hJWvcDctPT+Ela9wNy09P4SVr3A3LT0/EkO8v4sIQD8SQ7y/iwhAPxJDvL+LCEA/22SepuA6QD/bZJ6m4DpAP9tknqbgOkA/rWcIxyx7Qj+tZwjHLHtCP61nCMcse0I/ATuSJjm7QD8BO5ImObtAPzHmU2xxMjY/MeZTbHEyNj9uQ3urZLY6P25De6tktjo/6cQvBiD/Nj/pxC8GIP82Pw==", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Component=Residual (s)
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Overhead (s)=%{y}", + "legendgroup": "Residual (s)", + "marker": { + "color": "#9467BD", + "pattern": { + "shape": "" + } + }, + "name": "Residual (s)", + "orientation": "v", + "showlegend": true, + "textposition": "auto", + "type": "bar", + "x": { + "bdata": "AQEBAQEBAQEBAwMDAwMDAwMDBQUFBQUFBQUFCAgICAgICAgIEBAQECAgICA=", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "dtype": "f8" + }, + "yaxis": "y" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "barmode": "stack", + "height": 700, + "legend": { + "title": { + "text": "Component" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta
Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. Residual = delta not fully explained by TEE metrics (measurement noise / base model diff)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "categoryorder": "array", + "domain": [ + 0, + 0.98 + ], + "title": { + "text": "Concurrency" + }, + "type": "category" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0, + 0.98 + ], + "matches": "x", + "showticklabels": false, + "type": "category" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Overhead (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Overhead (s)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Client TTFT overhead attribution: stacked TEE components vs total delta\n", + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "df_enc_a = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "df_plain_a = df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n", + " columns={'client_ttft_s_p50': 'client_ttft_plain'}\n", + ")\n", + "df_attr = df_enc_a.merge(df_plain_a, on=DIMS)\n", + "\n", + "df_attr['client_ttft_delta'] = df_attr['client_ttft_s_p50'] - df_attr['client_ttft_plain']\n", + "df_attr['Network Hop (s)'] = df_attr['server_network_latency_ms_mean'] / 1000\n", + "df_attr['Input Encryption (s)']= df_attr['total_encryption_time_ms_mean'] / 1000\n", + "df_attr['Output Decryption (s)']= df_attr['total_decryption_time_ms_mean'] / 1000\n", + "df_attr['Residual (s)'] = (\n", + " df_attr['client_ttft_delta']\n", + " - df_attr['Network Hop (s)']\n", + " - df_attr['Input Encryption (s)']\n", + " - df_attr['Output Decryption (s)']\n", + ").clip(lower=0)\n", + "df_attr['out_tokens_label'] = df_attr['num_output_tokens'].astype(str) + ' output tokens'\n", + "\n", + "ATTR_COLS = ['Network Hop (s)', 'Input Encryption (s)', 'Output Decryption (s)', 'Residual (s)']\n", + "ATTR_COLORS = {\n", + " 'Network Hop (s)': '#FF7F0E',\n", + " 'Input Encryption (s)': '#D62728',\n", + " 'Output Decryption (s)':'#2CA02C',\n", + " 'Residual (s)': '#9467BD',\n", + "}\n", + "\n", + "df_attr_melt = df_attr.melt(\n", + " id_vars=['run_type', 'out_tokens_label', 'num_concurrent_requests', 'client_ttft_delta'],\n", + " value_vars=ATTR_COLS, var_name='Component', value_name='Overhead (s)',\n", + ").dropna(subset=['Overhead (s)'])\n", + "\n", + "fig = px.bar(\n", + " df_attr_melt,\n", + " x='num_concurrent_requests',\n", + " y='Overhead (s)',\n", + " color='Component',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " barmode='stack',\n", + " color_discrete_map=ATTR_COLORS,\n", + " category_orders={\n", + " 'num_concurrent_requests': CONC_ORDER,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'run_type': 'Run Type',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " },\n", + " title=(\n", + " 'Client TTFT Overhead Attribution: Encrypted − Non-Encrypted Delta
'\n", + " 'Stacked bars = measured TEE components. Total bar height = Enc TTFT − Plain TTFT. '\n", + " 'Residual = delta not fully explained by TEE metrics (measurement noise / base model diff).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(type='category')\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "cell-client-e2e", "metadata": {}, - "outputs": [], - "source": "fig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_end_to_end_latency_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_end_to_end_latency_s_p50': 'Client E2E Latency p50 (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client End-to-End Latency — p50 (faceted by Input Tokens)
'\n 'Full request duration as observed by the client. '\n 'Both prefill (input size) and TEE queueing (concurrency) push this up.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "2V92Tx4W3j/b+X5qvHTfP5EPejarPuk/EOm3rwPn7j9/2T15WKj3PxTQRNjw9AFA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "TDeJQWDl4j8v3SQGgZXrPx1aZDvfT/0/j+TyH9JvBUBz1xLyQU8HQCQofoy5KxNA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "Ne84RUdy8T83GsBbIEECQMHKoUW28/4/oWez6nO1AUA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "FK5H4XoU1j/yQc9m1efgP166SQwCK+k/+Q/pt68D8j/rc7UV+8v/P1R0JJf/EAhA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "4QuTqYJR3T93vp8aL93uP+hqK/aX3fU/bAn5oGezAUAQ6bevA2cQQBpR2ht8IRxA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client E2E Latency p50 (s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "mbuWkA967j+MSuoENJEDQJ88LNSaZgNAfh04Z0RpAkA=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client End-to-End Latency — p50
Full request duration as observed by the client. Grows faster for encrypted at high concurrency due to TEE queueing." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Client E2E Latency p50 (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_end_to_end_latency_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_end_to_end_latency_s_p50': 'Client E2E Latency p50 (s)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client End-to-End Latency — p50
'\n", + " 'Full request duration as observed by the client. '\n", + " 'Grows faster for encrypted at high concurrency due to TEE queueing.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "cell-client-toks", "metadata": {}, - "outputs": [], - "source": "# Per-request client generation speed\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_output_token_per_s_p50',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_output_token_per_s_p50': 'Client Output Tok/s p50 (per request)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client Output Throughput per Request — p50 (faceted by Input Tokens)
'\n 'After the first token, subsequent tokens stream at this rate. '\n 'Encrypted is bounded by TEE streaming decryption; '\n 'Non-Encrypted by server generation at high concurrency.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "idLe4ItHj0C/fR0451GNQEjhehQulYhANs07TtFoiEDSb18HzlOIQFtCPuhZ8IVA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "mG4Sg8CZiUAOT6+UZQyKQIhjXdxGoIhAxm00gLfmh0C+nxov3V97QFmGONbFZ3VA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "h6dXyjLigUDnHafoSFCBQIofY+7aGohAldQJaKLIgkA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ke18P3WukUAVjErqBFKQQNnO91Pj8oxAg8DKoUVuhkAAAAAAACR/QJjdk4eFU3RA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "ldQJaKJljUAXSFD8mKqLQEVHcvkPA4hAAd4CCQpJgEChZ7Pqcxh1QFHaG3xhGHVA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Client Output Tok/s p50 (per request)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "qFfKMsTJg0AdyeU/pOaBQJ0Rpb3BLohARdjw9Mpgg0A=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client Output Throughput per Request — p50
After the first token, subsequent tokens stream at this rate. Encrypted is limited by TEE streaming decryption speed; Non-Encrypted is limited by server generation speed at high concurrency." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Client Output Tok/s p50 (per request)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Per-request client generation speed\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_output_token_per_s_p50',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_output_token_per_s_p50': 'Client Output Tok/s p50 (per request)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client Output Throughput per Request — p50
'\n", + " 'After the first token, subsequent tokens stream at this rate. '\n", + " 'Encrypted is limited by TEE streaming decryption speed; '\n", + " 'Non-Encrypted is limited by server generation speed at high concurrency.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "id": "cell-total-throughput", "metadata": {}, - "outputs": [], - "source": "# Total system throughput — aggregate across all concurrent requests\nfig = px.line(\n df_all,\n x='num_concurrent_requests',\n y='client_total_output_throughput',\n color='label',\n symbol='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n symbol_map=SYMBOL_MAP,\n log_x=True,\n markers=True,\n category_orders={'in_tokens_label': INPUT_LABELS},\n labels={\n 'num_concurrent_requests': 'Concurrency (log scale)',\n 'client_total_output_throughput': 'Total Output Throughput (tok/s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Total Client Output Throughput — All Concurrent Requests (faceted by Input Tokens)
'\n 'Non-Encrypted scales nearly linearly with concurrency. '\n 'Encrypted ceiling drops as input tokens grow because each request takes longer to '\n 'encrypt + ship through the TEE.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "xLEubqO9X0C1pnnHKUplQARWDi2yDTlAgLdAguKnOkAawFsgQYE8QCUGgZVDezlA", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "EhQ/xtyNR0ApXI/C9Yg9QCSX/5B+yzVA6gQ0ETY8PED/snvysPAvQDY8vVKWoTRA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Encrypted", + "line": { + "color": "#EF553B", + "dash": "solid" + }, + "marker": { + "symbol": "circle" + }, + "mode": "lines+markers", + "name": "Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "iIVa07zjNUDoaiv2l0VBQAkbnl4p6z9AldQJaCJUQUA=", + "dtype": "f8" + }, + "yaxis": "y3" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=3900 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x", + "y": { + "bdata": "ZMxdS8i5ZUBGJXUCmsiAQMiYu5YQaYNAKjqSy/9nhUDtnjws1J6IQATnjCjtHn5A", + "dtype": "f8" + }, + "yaxis": "y" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=8000 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCBAg", + "dtype": "i1" + }, + "xaxis": "x2", + "y": { + "bdata": "Dr4wmSq+akDb+X5qvO5vQHzysFBrgnZA/kP67etbdkC0yHa+nwF2QPKwUGuaDHxA", + "dtype": "f8" + }, + "yaxis": "y2" + }, + { + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Input Tokens=16000 input tokens
Concurrency (log scale)=%{x}
Total Output Throughput (tok/s)=%{y}", + "legendgroup": "Non-Encrypted", + "line": { + "color": "#636EFA", + "dash": "solid" + }, + "marker": { + "symbol": "square" + }, + "mode": "lines+markers", + "name": "Non-Encrypted", + "orientation": "v", + "showlegend": false, + "type": "scatter", + "x": { + "bdata": "AQMFCA==", + "dtype": "i1" + }, + "xaxis": "x3", + "y": { + "bdata": "7zhFR3IZWkB8YTJVMHZeQGiz6nO1YWlAK/aX3ZN4dUA=", + "dtype": "f8" + }, + "yaxis": "y3" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=3900 input tokens", + "x": 0.15666666666666665, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=8000 input tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Input Tokens=16000 input tokens", + "x": 0.8233333333333333, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.5, + "yanchor": "middle", + "yref": "paper" + } + ], + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Total Client Output Throughput — All Concurrent Requests
Non-Encrypted scales nearly linearly with concurrency. Encrypted collapses at higher concurrencies due to TEE queuing adding large wall-clock delays." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.3133333333333333 + ], + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.3333333333333333, + 0.6466666666666666 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.6666666666666666, + 0.98 + ], + "matches": "x", + "ticktext": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "tickvals": [ + 1, + 3, + 5, + 8, + 16, + 32 + ], + "title": { + "text": "Concurrency (log scale)" + }, + "type": "log" + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "Total Output Throughput (tok/s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Total system throughput — aggregate across all concurrent requests\n", + "fig = px.line(\n", + " df_all,\n", + " x='num_concurrent_requests',\n", + " y='client_total_output_throughput',\n", + " color='label',\n", + " symbol='label',\n", + " facet_col='in_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " symbol_map=SYMBOL_MAP,\n", + " log_x=True,\n", + " markers=True,\n", + " labels={\n", + " 'num_concurrent_requests': 'Concurrency (log scale)',\n", + " 'client_total_output_throughput': 'Total Output Throughput (tok/s)',\n", + " 'label': 'Model',\n", + " 'in_tokens_label': 'Input Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Total Client Output Throughput — All Concurrent Requests
'\n", + " 'Non-Encrypted scales nearly linearly with concurrency. '\n", + " 'Encrypted collapses at higher concurrencies due to TEE queuing adding large wall-clock delays.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.update_xaxes(tickvals=CONC_ORDER, ticktext=CONC_STR)\n", + "fig.show()" + ] }, { "cell_type": "markdown", "id": "cell-dist-hdr", "metadata": {}, - "source": "## 6. Per-Request Distributions\n\nBox plots using individual request data from all 10 rounds, faceted by **Input Tokens**.\nError requests (where `error_code` is set) are excluded." + "source": [ + "## 6. Per-Request Distributions\n", + "\n", + "Box plots using individual request data from all runs.\n", + "- **Multi Run (10x)** provides the richest distributions (10–320 requests per scenario across 10 rounds).\n", + "- **Single Run (1x)** covers only the N simultaneous requests in a single round (1–32 points per box depending on concurrency).\n", + "\n", + "Error requests (where `error_code` is set) are excluded." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 38, "id": "cell-load-individual", "metadata": {}, - "outputs": [], - "source": "def _parse_fname(fname):\n \"\"\"Extract (input_tokens, output_tokens, concurrency) from benchmark filename.\n\n Filename format:\n synthetic______stream__*\n \"\"\"\n base = os.path.basename(str(fname)).replace('_individual_responses.json', '')\n parts = base.split('_')\n try:\n return int(parts[3]), int(parts[4]), int(parts[5])\n except (IndexError, ValueError):\n return None, None, None\n\ndfs_ind = []\nfor key, meta in DATASETS.items():\n try:\n df_ind = read_perf_eval_json_files(meta['run_dir'], type='individual_responses')\n if df_ind.empty:\n continue\n df_ind['label'] = meta['label']\n df_ind['run_type'] = meta['run_type']\n parsed = df_ind['filename'].apply(lambda f: pd.Series(_parse_fname(f)))\n df_ind['num_input_tokens'] = parsed[0]\n df_ind['num_output_tokens'] = parsed[1]\n df_ind['num_concurrent_requests'] = parsed[2]\n dfs_ind.append(df_ind)\n except Exception as e:\n print(f'Warning: could not load {key}: {e}')\n\ndf_individual = pd.concat(dfs_ind, ignore_index=True)\ndf_individual = df_individual.dropna(\n subset=['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests', 'client_ttft_s']\n)\ndf_individual['num_input_tokens'] = df_individual['num_input_tokens'].astype(int)\ndf_individual['num_output_tokens'] = df_individual['num_output_tokens'].astype(int)\ndf_individual['num_concurrent_requests'] = df_individual['num_concurrent_requests'].astype(int)\ndf_individual['in_tokens_label'] = df_individual['num_input_tokens'].apply(lambda n: f'{n:,} input tokens')\ndf_individual['concurrency_str'] = df_individual['num_concurrent_requests'].astype(str)\ndf_individual['is_error'] = df_individual['error_code'].notna()\ndf_individual['in_tokens_label'] = pd.Categorical(\n df_individual['in_tokens_label'], categories=INPUT_LABELS, ordered=True\n)\n\nprint(f'Loaded {len(df_individual):,} individual request records')\ndf_individual.groupby(['label', 'in_tokens_label', 'is_error'])[['client_ttft_s']].count().rename(\n columns={'client_ttft_s': 'count'}\n)" + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loaded 2,767 individual request records\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
count
labelrun_typeis_error
EncryptedSingle Run (1x)False0
Multi Run (10x)False1297
Non-EncryptedSingle Run (1x)False0
Multi Run (10x)False1470
\n", + "
" + ], + "text/plain": [ + " count\n", + "label run_type is_error \n", + "Encrypted Single Run (1x) False 0\n", + " Multi Run (10x) False 1297\n", + "Non-Encrypted Single Run (1x) False 0\n", + " Multi Run (10x) False 1470" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def _parse_fname(fname):\n", + " \"\"\"Extract (out_tokens, concurrency) from benchmark filename.\"\"\"\n", + " base = os.path.basename(str(fname)).replace('_individual_responses.json', '')\n", + " parts = base.split('_')\n", + " try:\n", + " return int(parts[4]), int(parts[5])\n", + " except (IndexError, ValueError):\n", + " return None, None\n", + "\n", + "dfs_ind = []\n", + "for key, meta in DATASETS.items():\n", + " try:\n", + " df_ind = read_perf_eval_json_files(meta['run_dir'], type='individual_responses')\n", + " if df_ind.empty:\n", + " continue\n", + " df_ind['label'] = meta['label']\n", + " df_ind['run_type'] = meta['run_type']\n", + " parsed = df_ind['filename'].apply(lambda f: pd.Series(_parse_fname(f)))\n", + " df_ind['num_output_tokens'] = parsed[0]\n", + " df_ind['num_concurrent_requests'] = parsed[1]\n", + " dfs_ind.append(df_ind)\n", + " except Exception as e:\n", + " print(f'Warning: could not load {key}: {e}')\n", + "\n", + "df_individual = pd.concat(dfs_ind, ignore_index=True)\n", + "df_individual = df_individual.dropna(\n", + " subset=['num_output_tokens', 'num_concurrent_requests', 'client_ttft_s']\n", + ")\n", + "df_individual['num_output_tokens'] = df_individual['num_output_tokens'].astype(int)\n", + "df_individual['num_concurrent_requests'] = df_individual['num_concurrent_requests'].astype(int)\n", + "df_individual['out_tokens_label'] = df_individual['num_output_tokens'].astype(str) + ' output tokens'\n", + "df_individual['concurrency_str'] = df_individual['num_concurrent_requests'].astype(str)\n", + "df_individual['is_error'] = df_individual['error_code'].notna()\n", + "df_individual['run_type'] = pd.Categorical(\n", + " df_individual['run_type'],\n", + " categories=['Single Run (1x)', 'Multi Run (10x)'],\n", + " ordered=True\n", + ")\n", + "\n", + "print(f'Loaded {len(df_individual):,} individual request records')\n", + "df_individual.groupby(['label', 'run_type', 'is_error'])[['client_ttft_s']].count().rename(\n", + " columns={'client_ttft_s': 'count'}\n", + ")" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "id": "cell-box-client-ttft", "metadata": {}, - "outputs": [], - "source": "df_box = df_individual[~df_individual['is_error']].copy()\n\nfig = px.box(\n df_box,\n x='concurrency_str',\n y='client_ttft_s',\n color='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n points='outliers',\n labels={\n 'concurrency_str': 'Concurrency',\n 'client_ttft_s': 'Client TTFT (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Client TTFT Distribution per Concurrency — faceted by Input Tokens
'\n 'Encrypted shows higher median AND wider spread due to variable TEE network latency. '\n 'Spread grows with both input size and concurrency.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Client TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "boxmode": "group", + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Client TTFT Distribution per Concurrency
Encrypted shows higher median AND wider spread due to variable TEE network latency. High concurrency increases spread (TEE queue wait time variance)." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0, + 0.98 + ], + "title": { + "text": "Concurrency" + } + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0, + 0.98 + ], + "matches": "x", + "showticklabels": false + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Client TTFT (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Client TTFT (s)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "df_box = df_individual[~df_individual['is_error']].copy()\n", + "\n", + "fig = px.box(\n", + " df_box,\n", + " x='concurrency_str',\n", + " y='client_ttft_s',\n", + " color='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'concurrency_str': CONC_STR,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " points='outliers',\n", + " labels={\n", + " 'concurrency_str': 'Concurrency',\n", + " 'client_ttft_s': 'Client TTFT (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label':'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Client TTFT Distribution per Concurrency
'\n", + " 'Encrypted shows higher median AND wider spread due to variable TEE network latency. '\n", + " 'High concurrency increases spread (TEE queue wait time variance).'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "id": "cell-box-server-ttft", "metadata": {}, - "outputs": [], - "source": "fig = px.box(\n df_box,\n x='concurrency_str',\n y='server_ttft_s',\n color='label',\n facet_col='in_tokens_label',\n color_discrete_map=COLOR_MAP,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n points='outliers',\n labels={\n 'concurrency_str': 'Concurrency',\n 'server_ttft_s': 'Server TTFT (s)',\n 'label': 'Model',\n 'in_tokens_label': 'Input Tokens',\n },\n title=(\n 'Server TTFT Distribution per Concurrency — faceted by Input Tokens
'\n 'Server-side distribution. At medium concurrency, encrypted may show LOWER server TTFT '\n 'because TEE de-batching reduces the effective batch size seen by the server.'\n ),\n)\nfig.update_layout(height=450, width=1200, template='plotly_white')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Encrypted", + "marker": { + "color": "#EF553B" + }, + "name": "Encrypted", + "notched": false, + "offsetgroup": "Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "boxpoints": "outliers", + "hovertemplate": "Model=Non-Encrypted
Run Type=Multi Run (10x)
Output Tokens=100 output tokens
Concurrency=%{x}
Server TTFT (s)=%{y}", + "legendgroup": "Non-Encrypted", + "marker": { + "color": "#636EFA" + }, + "name": "Non-Encrypted", + "notched": false, + "offsetgroup": "Non-Encrypted", + "orientation": "v", + "showlegend": true, + "type": "box", + "x": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "1", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "16", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "8", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "32", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "5", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "x0": " ", + "xaxis": "x", + "y": { + "bdata": "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", + "dtype": "f8" + }, + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Output Tokens=100 output tokens", + "x": 0.49, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Multi Run (10x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.2425, + "yanchor": "middle", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Run Type=Single Run (1x)", + "textangle": 90, + "x": 0.98, + "xanchor": "left", + "xref": "paper", + "y": 0.7575000000000001, + "yanchor": "middle", + "yref": "paper" + } + ], + "boxmode": "group", + "height": 700, + "legend": { + "title": { + "text": "Model" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Server TTFT Distribution per Concurrency
Server-side distribution. At medium concurrencies, encrypted may show LOWER server TTFT because TEE de-batching reduces effective batch size seen by the server." + }, + "width": 1100, + "xaxis": { + "anchor": "y", + "categoryarray": [ + "1", + "3", + "5", + "8", + "16", + "32" + ], + "categoryorder": "array", + "domain": [ + 0, + 0.98 + ], + "title": { + "text": "Concurrency" + } + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0, + 0.98 + ], + "matches": "x", + "showticklabels": false + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 0.485 + ], + "title": { + "text": "Server TTFT (s)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.515, + 1 + ], + "matches": "y", + "title": { + "text": "Server TTFT (s)" + } + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = px.box(\n", + " df_box,\n", + " x='concurrency_str',\n", + " y='server_ttft_s',\n", + " color='label',\n", + " facet_col='out_tokens_label',\n", + " facet_row='run_type',\n", + " color_discrete_map=COLOR_MAP,\n", + " category_orders={\n", + " 'concurrency_str': CONC_STR,\n", + " 'run_type': ['Single Run (1x)', 'Multi Run (10x)'],\n", + " },\n", + " points='outliers',\n", + " labels={\n", + " 'concurrency_str': 'Concurrency',\n", + " 'server_ttft_s': 'Server TTFT (s)',\n", + " 'label': 'Model',\n", + " 'out_tokens_label':'Output Tokens',\n", + " 'run_type': 'Run Type',\n", + " },\n", + " title=(\n", + " 'Server TTFT Distribution per Concurrency
'\n", + " 'Server-side distribution. At medium concurrencies, encrypted may show LOWER server TTFT '\n", + " 'because TEE de-batching reduces effective batch size seen by the server.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=700, width=1100, template='plotly_white')\n", + "fig.show()" + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "id": "cell-scatter-tee", "metadata": {}, - "outputs": [], - "source": "# Per-request: TEE network latency vs server TTFT (encrypted only), one column per Input Tokens\ndf_enc_ind = df_individual[\n (df_individual['label'] == 'Encrypted') &\n (~df_individual['is_error']) &\n (df_individual['server_network_latency_ms'].notna())\n].copy()\n\nfig = px.scatter(\n df_enc_ind,\n x='server_ttft_s',\n y='server_network_latency_ms',\n color='concurrency_str',\n facet_col='in_tokens_label',\n opacity=0.55,\n category_orders={\n 'concurrency_str': CONC_STR,\n 'in_tokens_label': INPUT_LABELS,\n },\n labels={\n 'server_ttft_s': 'Server TTFT (s)',\n 'server_network_latency_ms': 'TEE Network Latency (ms)',\n 'in_tokens_label': 'Input Tokens',\n 'concurrency_str': 'Concurrency',\n },\n title=(\n 'Per-Request: TEE Network Latency vs Server TTFT — Encrypted (faceted by Input Tokens)
'\n 'How network latency varies relative to server prefill time. '\n 'A flatter horizontal spread = network latency is independent of server load.'\n ),\n)\nfig.update_layout(height=420, width=1300, template='plotly_white')\nfig.show()" + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=1
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": true, + "type": "scattergl", + "x": { + "bdata": "AAAAAOyTtz8AAAAAiBW3PwAAAACkG7c/AAAAAIzxtj8AAAAASMG2PwAAAAC0G7c/AAAAALzPtj8AAAAAzGe3PwAAAAAUDrc/AAAAAHhptz8AAACAAq7jPwAAAAC0nOM/AAAAgMKk4z8AAACAs6HjPwAAAIAv2eM/AAAAgKOi4z8AAACAJp/jPwAAAICAtOM/AAAAgGid4z8AAAAAW7XjPwAAAACI98s/AAAAAIhAzD8AAAAA7t3LPwAAAAAoJsw/AAAAAIRBzD8AAAAAPCHMPwAAAACeWsw/AAAAAGw4zD8AAAAAalbMPwAAAADUfsw/", + "dtype": "f8" + }, + "xaxis": "x", + "y": [ + 759.4072818756104, + 236.33646965026855, + 336.59958839416504, + 311.54370307922363, + 219.895601272583, + 215.64316749572754, + 319.4153308868408, + 272.5555896759033, + 313.20858001708984, + 323.53830337524414, + 1202.0225524902344, + 879.0848255157471, + 848.1519222259521, + 855.1733493804932, + 926.6860485076904, + 852.0355224609375, + 843.5640335083008, + 1024.6400833129883, + 853.2867431640625, + 853.0251979827881, + 589.7412300109863, + 380.8267116546631, + 379.49371337890625, + 501.05905532836914, + 505.5065155029297, + 378.99303436279297, + 385.34069061279297, + 381.4890384674072, + 382.2963237762451, + 383.10837745666504 + ], + "yaxis": "y" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=3
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAgMis4z8AAAAAJzb1PwAAAAAnNvU/AAAAAHbE4z8AAADAADX1PwAAAMAANfU/AAAAAI7G4z8AAACABDj1PwAAAIAEOPU/AAAAgDDJ4z8AAAAAdDf1PwAAAAB0N/U/AAAAgGUK5D8AAACAYTz1PwAAAIBhPPU/AAAAgEna4z8AAABAwTr1PwAAAEDBOvU/AAAAABv54z8AAADAdjL1PwAAAMB2MvU/AAAAgIS+4z8AAACAHYv1PwAAAIAdi/U/AAAAgBvC4z8AAABALTn1PwAAAEAtOfU/AAAAgDi/4z8AAADAOC71PwAAAMA4LvU/AAAAAIwNzD8AAAAACVHaPwAAAAAJUdo/AAAAAPTOyz8AAAAACJHMPwAAAACQDc0/AAAAADqkzD8AAAAAUjjMPwAAAABmD8w/AAAAAK5FzD8AAAAAxzfaPwAAAADHN9o/AAAAALIEzD8AAAAAlsXLPwAAAACMMcw/AAAAABz4yz8AAAAAFIrMPwAAAACiNto/AAAAAKI22j8AAAAAqHvMPwAAAACgYto/AAAAAKBi2j8AAAAAWs/LPwAAAACI18s/AAAAAD7Fyz8AAAAAPtzLPwAAAADc1cs/AAAAAOxazD8AAAAAcIjMPwAAAACURcw/AAAAAMAOtz8AAAAA4OXEPwAAAADg5cQ/AAAAAEDAtz8AAAAAiDS3PwAAAADUlcQ/AAAAANSVxD8AAAAA6Cq3PwAAAACsf7c/AAAAAPh+tz8AAAAA7L22PwAAAADY/LY/AAAAADTTtj8AAAAA1MW2PwAAAABExLY/AAAAABgAtz8AAAAAyBS3PwAAAADYf7c/AAAAAKyAtz8AAAAAPJa3PwAAAAD087c/AAAAAASaxD8AAAAABJrEPwAAAADQvrc/AAAAADrgxD8AAAAAOuDEPwAAAABM4bc/AAAAAJjPtz8AAAAAECa3PwAAAAAQSbc/", + "dtype": "f8" + }, + "xaxis": "x2", + "y": [ + 1258.6746215820312, + 2722.7532863616943, + 2803.9143085479736, + 2068.0651664733887, + 2057.598352432251, + 1944.9188709259033, + 2107.3992252349854, + 2104.8364639282227, + 2043.5593128204346, + 1877.270221710205, + 1830.6100368499756, + 1879.3046474456787, + 1878.0694007873535, + 1880.082368850708, + 2021.653413772583, + 2064.936399459839, + 2059.0946674346924, + 2054.253101348877, + 2055.856466293335, + 1865.6654357910156, + 2244.5435523986816, + 2052.4344444274902, + 2073.854923248291, + 1891.4117813110352, + 2059.2660903930664, + 2038.8977527618408, + 2001.1777877807617, + 1864.023208618164, + 1825.735330581665, + 2008.4795951843262, + 536.1137390136719, + 1044.6932315826416, + 1155.7385921478271, + 659.0695381164551, + 464.8323059082031, + 621.2773323059082, + 627.3536682128906, + 544.1865921020508, + 504.1217803955078, + 870.4922199249268, + 3192.0669078826904, + 2698.997974395752, + 772.4997997283936, + 559.0486526489258, + 780.2886962890625, + 621.6676235198975, + 538.1507873535156, + 966.51291847229, + 653.1882286071777, + 648.1530666351318, + 660.8974933624268, + 757.2948932647705, + 657.2067737579346, + 513.5495662689209, + 602.5941371917725, + 605.0429344177246, + 585.2916240692139, + 392.2238349914551, + 384.8261833190918, + 401.52502059936523, + 435.6105327606201, + 680.687665939331, + 735.2101802825928, + 321.11096382141113, + 330.5389881134033, + 353.3201217651367, + 579.1969299316406, + 330.89160919189453, + 244.7800636291504, + 309.6165657043457, + 297.71900177001953, + 277.3141860961914, + 319.6570873260498, + 601.6418933868408, + 1014.8530006408691, + 1880.1770210266113, + 233.01005363464355, + 1746.8945980072021, + 318.756103515625, + 488.27409744262695, + 315.0789737701416, + 2557.791233062744, + 338.0138874053955, + 343.92786026000977, + 392.8518295288086, + 410.4430675506592, + 309.08989906311035, + 282.3834419250488, + 230.64279556274414, + 314.69035148620605 + ], + "yaxis": "y2" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=5
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAFqv4z8AAAAA66DkPwAAAADroOQ/AAAAAOug5D8AAAAA66DkPwAAAIB7++M/AAAAAFq35D8AAAAAWrfkPwAAAABat+Q/AAAAAFq35D8AAAAA0MDjPwAAAIA2zuQ/AAAAgDbO5D8AAACANs7kPwAAAIA2zuQ/AAAAAK/U4z8AAACA2ZPkPwAAAIDZk+Q/AAAAgNmT5D8AAACA2ZPkPwAAAAAhweM/AAAAAH6d5D8AAAAAfp3kPwAAAAB+neQ/AAAAgG2p4z8AAACAmgfkPwAAAIDgzeM/AAAAABqO5D8AAAAAGo7kPwAAAAAajuQ/AAAAABqO5D8AAACAhfnjPwAAAECkLPU/AAAAQKQs9T8AAACAEY3kPwAAAIARjeQ/AAAAgBGN5D8AAACAhOvjPwAAAIBh5uM/AAAAgPO45D8AAACA87jkPwAAAIDzuOQ/AAAAgPO45D8AAAAAdwXkPwAAAIA8weM/AAAAAEiO5D8AAAAASI7kPwAAAABIjuQ/AAAAgPc49T8AAACA9zj1PwAAAABmzMQ/AAAAAGbMxD8AAAAAUp3UPwAAAABSndQ/AAAAAFKd1D8AAAAARLvEPwAAAABEu8Q/AAAAAAyHxD8AAAAADIfEPwAAAACmidQ/AAAAAKaJ1D8AAAAAponUPwAAAACMx8Q/AAAAAIzHxD8AAAAAGYPUPwAAAAAZg9Q/AAAAABmD1D8AAAAAxLrEPwAAAADEusQ/AAAAAMN51D8AAAAAw3nUPwAAAADDedQ/AAAAAOacxD8AAAAA5pzEPwAAAABoTrc/AAAAAAirtz8AAAAAyM7EPwAAAADIzsQ/AAAAAEOG1D8AAAAAQ4bUPwAAAABDhtQ/AAAAAOxEtz8AAAAA8LK2PwAAAACQDrc/AAAAAMB8tz8AAAAAsOq3PwAAAABggbc/AAAAAAiGtz8AAAAAIpfUPwAAAAAil9Q/AAAAACKX1D8AAAAA/sLEPwAAAAD+wsQ/AAAAAASxxD8AAAAABLHEPwAAAADwt8Q/AAAAAPC3xD8AAAAA9E23PwAAAADIsrc/AAAAAGyGtz8AAAAAS1raPwAAAACGXek/AAAAAIZd6T8AAAAAS1raPwAAAAB8D8w/AAAAAIZd6T8AAAAAWIfMPwAAAACQH8w/AAAAAAYNzT8AAAAA9mfaPwAAAAD2Z9o/AAAAAK1B2j8AAAAArUHaPwAAAID1Vek/AAAAgPVV6T8AAACA9VXpPwAAAABxLto/AAAAAHEu2j8AAAAAkljpPwAAAACSWOk/AAAAAJJY6T8AAAAA2GzMPwAAAABoRMw/AAAAAKQ+zD8AAAAAdi7MPwAAAACQVNo/AAAAAJBU2j8AAAAAdCfMPwAAAAAZUdo/AAAAABlR2j8AAAAAi4/aPwAAAACLj9o/AAAAADKC2j8AAAAAMoLaPwAAAADsJsw/AAAAAAx1zD8AAAAA3ADMPwAAAADxUdo/AAAAAPFR2j8AAAAA/lzaPwAAAAD+XNo/AAAAAHTezD8AAAAAfDnMPwAAAABm+cw/AAAAAGa4zD8AAAAAkrLMPwAAAADMNMw/AAAAAKp1zD8AAAAAWi/MPwAAAADmiMw/", + "dtype": "f8" + }, + "xaxis": "x3", + "y": [ + 1013.4212970733643, + 1830.6617736816406, + 1833.6057662963867, + 1770.4296112060547, + 1802.7949333190918, + 1477.3037433624268, + 1500.3600120544434, + 1410.4766845703125, + 1483.0946922302246, + 1451.024055480957, + 1301.8262386322021, + 1210.1588249206543, + 1302.5741577148438, + 1361.4885807037354, + 1272.2737789154053, + 1316.3678646087646, + 1145.369529724121, + 1289.6525859832764, + 1259.6793174743652, + 1331.3343524932861, + 1304.9437999725342, + 1363.42453956604, + 1253.4196376800537, + 1296.6222763061523, + 1363.560438156128, + 1073.9951133728027, + 1266.3280963897705, + 1285.203218460083, + 2007.4818134307861, + 2046.9996929168701, + 2088.247776031494, + 1371.373176574707, + 1916.5713787078857, + 1956.0487270355225, + 1618.9649105072021, + 2034.8107814788818, + 1699.0530490875244, + 1350.583791732788, + 865.8175468444824, + 1455.3749561309814, + 1339.7419452667236, + 1399.4512557983398, + 1219.7959423065186, + 1320.1966285705566, + 894.6499824523926, + 1783.0078601837158, + 1675.2965450286865, + 1714.463472366333, + 1617.217779159546, + 1756.1964988708496, + 410.2516174316406, + 471.47107124328613, + 944.5841312408447, + 965.1026725769043, + 981.8625450134277, + 649.996280670166, + 609.6494197845459, + 422.1787452697754, + 476.79829597473145, + 534.7363948822021, + 908.6027145385742, + 649.2974758148193, + 572.4537372589111, + 659.3573093414307, + 536.8130207061768, + 593.8208103179932, + 745.8651065826416, + 576.5888690948486, + 723.3004570007324, + 619.1606521606445, + 689.8984909057617, + 673.1393337249756, + 564.5215511322021, + 614.189863204956, + 285.8576774597168, + 591.6001796722412, + 809.3037605285645, + 483.0021858215332, + 559.4935417175293, + 830.6348323822021, + 856.8291664123535, + 554.2423725128174, + 577.5830745697021, + 333.03046226501465, + 355.9553623199463, + 670.0417995452881, + 409.29532051086426, + 475.8167266845703, + 862.1277809143066, + 855.7450771331787, + 505.4495334625244, + 529.7882556915283, + 552.706241607666, + 384.22179222106934, + 477.40650177001953, + 787.919282913208, + 588.2573127746582, + 314.375638961792, + 278.65123748779297, + 395.40696144104004, + 692.0220851898193, + 1624.4335174560547, + 1745.5775737762451, + 2151.5324115753174, + 489.0007972717285, + 2262.4504566192627, + 652.8668403625488, + 2877.4781227111816, + 1886.7228031158447, + 1813.4582042694092, + 1862.626314163208, + 840.4631614685059, + 876.6181468963623, + 2558.4874153137207, + 1235.6352806091309, + 1409.6918106079102, + 1269.536018371582, + 1531.0993194580078, + 1396.1129188537598, + 1330.2421569824219, + 1550.6842136383057, + 1212.0871543884277, + 384.7510814666748, + 642.0013904571533, + 791.1643981933594, + 1363.4285926818848, + 878.8125514984131, + 772.5403308868408, + 651.8421173095703, + 760.1480484008789, + 781.6283702850342, + 930.1626682281494, + 942.3007965087891, + 1479.5231819152832, + 422.5156307220459, + 408.51831436157227, + 656.569242477417, + 1092.0183658599854, + 747.8573322296143, + 857.121467590332, + 1244.0872192382812, + 390.23327827453613, + 509.5396041870117, + 387.2194290161133, + 775.763750076294, + 469.9666500091553, + 573.8739967346191, + 493.5951232910156, + 630.0005912780762, + 391.3547992706299 + ], + "yaxis": "y3" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=8
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "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", + "dtype": "f8" + }, + "xaxis": "x4", + "y": [ + 531.909704208374, + 663.8169288635254, + 679.3646812438965, + 660.9869003295898, + 1020.9603309631348, + 1016.5135860443115, + 1153.958797454834, + 1197.1101760864258, + 740.6628131866455, + 739.1860485076904, + 914.8924350738525, + 854.5880317687988, + 809.9937438964844, + 806.3721656799316, + 312.1016025543213, + 224.3192195892334, + 463.78231048583984, + 554.4703006744385, + 636.570930480957, + 657.9291820526123, + 646.0192203521729, + 525.5522727966309, + 849.0045070648193, + 805.5927753448486, + 867.6764965057373, + 939.3923282623291, + 930.410623550415, + 862.7047538757324, + 867.5277233123779, + 739.5236492156982, + 867.4871921539307, + 839.9665355682373, + 801.4123439788818, + 843.9264297485352, + 865.1125431060791, + 992.584228515625, + 708.5554599761963, + 808.2640171051025, + 498.68226051330566, + 324.20969009399414, + 491.59932136535645, + 492.5427436828613, + 318.0582523345947, + 331.19750022888184, + 279.18338775634766, + 351.92346572875977, + 349.1191864013672, + 444.61584091186523, + 563.3335113525391, + 576.0266780853271, + 825.8743286132812, + 410.7067584991455, + 402.77743339538574, + 414.5183563232422, + 361.8800640106201, + 395.59364318847656, + 323.8539695739746, + 524.7201919555664, + 605.2098274230957, + 528.7351608276367, + 1112.633228302002, + 1096.6989994049072, + 572.1991062164307, + 774.1706371307373, + 673.304557800293, + 593.7709808349609, + 586.1072540283203, + 601.2461185455322, + 509.31572914123535, + 507.5387954711914, + 454.7419548034668, + 583.5590362548828, + 675.6391525268555, + 687.8159046173096, + 318.59302520751953, + 545.3941822052002, + 2283.6859226226807, + 2266.725778579712, + 2219.111680984497, + 2259.2296600341797, + 2320.1980590820312, + 2481.044054031372, + 2609.929084777832, + 1965.4638767242432, + 1942.009449005127, + 1927.6208877563477, + 2047.8665828704834, + 2149.0349769592285, + 2128.2055377960205, + 626.1646747589111, + 638.5297775268555, + 2161.9584560394287, + 1931.0104846954346, + 2194.7364807128906, + 2144.26589012146, + 2190.624952316284, + 2803.769826889038, + 2497.0715045928955, + 2641.6666507720947, + 2675.499439239502, + 2429.8958778381348, + 2923.114538192749, + 2690.22798538208, + 2685.938596725464, + 2713.0439281463623, + 2693.3889389038086, + 2826.241970062256, + 2449.6207237243652, + 2839.8983478546143, + 2913.597822189331, + 2703.6736011505127, + 2683.544874191284, + 2123.5873699188232, + 608.4189414978027, + 908.5049629211426, + 493.2987689971924, + 612.4534606933594, + 583.510160446167, + 1163.1743907928467, + 784.4836711883545, + 986.7000579833984, + 1277.6415348052979, + 1009.3669891357422, + 536.7722511291504, + 839.7636413574219, + 921.5049743652344, + 902.8415679931641, + 1246.4876174926758, + 1663.8262271881104, + 1411.4642143249512, + 1200.3562450408936, + 517.4627304077148, + 832.4389457702637, + 978.7817001342773, + 861.2825870513916, + 681.2553405761719, + 542.7818298339844, + 658.1284999847412, + 579.2326927185059, + 1784.7051620483398, + 1828.890085220337, + 1505.7296752929688, + 745.6450462341309, + 890.95139503479, + 775.9757041931152, + 773.5261917114258, + 914.9651527404785, + 666.9349670410156, + 587.0335102081299, + 734.7972393035889, + 731.6906452178955, + 526.9522666931152, + 1315.1626586914062, + 1494.8372840881348, + 1295.161247253418, + 1460.8209133148193, + 2328.8865089416504, + 2205.2156925201416, + 2305.2852153778076, + 2255.8236122131348, + 1344.7368144989014, + 1548.9280223846436, + 1493.741750717163, + 1454.5331001281738, + 2109.973669052124, + 2302.114486694336, + 1050.590991973877, + 1570.9455013275146, + 2398.146867752075, + 2267.895221710205, + 2376.0945796966553, + 1707.1049213409424, + 1029.2079448699951, + 1722.5220203399658, + 1255.5875778198242, + 1832.6830863952637, + 1765.1269435882568, + 1602.663516998291, + 1783.0533981323242, + 1655.778408050537, + 1506.1166286468506, + 1392.1728134155273, + 1406.125783920288, + 1545.1171398162842, + 1477.062702178955, + 1313.7953281402588, + 906.9123268127441, + 1432.0282936096191, + 1726.881980895996, + 1801.1679649353027, + 1317.9469108581543, + 2195.9245204925537, + 2257.545232772827, + 2090.282917022705, + 2146.653652191162, + 1467.1337604522705, + 1482.7947616577148, + 1360.2852821350098, + 1449.5320320129395, + 1412.9576683044434, + 1469.0780639648438, + 1934.2007637023926, + 2072.9939937591553, + 2198.2553005218506, + 2042.2184467315674, + 1966.2463665008545, + 2163.73610496521, + 2128.0579566955566, + 1929.8014640808105, + 1739.9909496307373, + 1979.034423828125, + 1911.0758304595947, + 1747.4327087402344, + 1784.4324111938477, + 1923.0461120605469, + 1875.983476638794, + 1919.3899631500244, + 1739.274263381958, + 2005.3367614746094, + 1798.2430458068848, + 1910.4690551757812, + 1887.7453804016113, + 1022.7031707763672, + 1009.3433856964111 + ], + "yaxis": "y4" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=16
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAgDxZ6T8AAACAPFnpPwAAAIA8Wek/AAAAANy9CEAAAAAA3L0IQAAAAADcvQhAAAAAANy9CEAAAAAA3L0IQAAAAADcvQhAAAAAANy9CEAAAAAA3L0IQAAAAADcvQhAAAAAANy9CEAAAAAA3L0IQAAAAADcvQhAAAAAANy9CEAAAAAg8r4IQAAAACDyvghAAAAAIPK+CEAAAAAg8r4IQAAAACDyvghAAAAAIPK+CEAAAAAg8r4IQAAAACDyvghAAAAAIPK+CEAAAAAg8r4IQAAAAOA2uQhAAAAA4Da5CEAAAADgNrkIQAAAAOA2uQhAAAAA4Da5CEAAAADgNrkIQAAAAOA2uQhAAAAA4Da5CEAAAADgNrkIQAAAAADwNMw/AAAAgJxq6T8AAACAnGrpPwAAAICcauk/AAAAAC9n6T8AAAAAL2fpPwAAAAAvZ+k/AAAAAJBS6T8AAAAAkFLpPwAAAACQUuk/AAAAAJBS6T8AAAAAhm7MPwAAAABk1cs/AAAAAFAYzD8AAAAArAzMPwAAAAC4JMw/AAAAAIoyzD8AAAAAdmbMPwAAAADm+cs/AAAAAKAZzD8AAAAAJnvMPwAAAACExcw/AAAAABg8zD8AAAAABmHMPwAAAABeEcw/AAAAAPSZzD8AAAAABI/MPwAAAACqB8w/AAAAADTq+D8AAAAANOr4PwAAAAA06vg/AAAAADTq+D8AAAAANOr4PwAAAABeVdo/AAAAAF5V2j8AAAAAOfb4PwAAAAA59vg/AAAAADn2+D8AAAAAOfb4PwAAAAA59vg/AAAAgMJX6T8AAACAwlfpPwAAAIDCV+k/AAAAwAv4+D8AAADAC/j4PwAAAMAL+Pg/AAAAwAv4+D8AAADAC/j4PwAAAIA1a+k/AAAAgDVr6T8AAACANWvpPwAAAICw8/g/AAAAgLDz+D8AAACAsPP4PwAAAICw8/g/AAAAgLDz+D8AAACAQFrpPwAAAIBAWuk/AAAAgEBa6T8AAABAW/D4PwAAAEBb8Pg/AAAAQFvw+D8AAABAW/D4PwAAAEBb8Pg/AAAAgN1o6T8AAACA3WjpPwAAAIDdaOk/AAAAgN1o6T8AAACAzvD4PwAAAIDO8Pg/AAAAgM7w+D8AAACAzvD4PwAAAIDO8Pg/AAAAgGZ86T8AAACAZnzpPwAAAIBmfOk/AAAAAHjmyz8AAAAA+DLNPwAAAAA8Psw/AAAAAO4+2j8AAAAA7j7aPwAAAAA6GMw/AAAAANoHzD8AAAAAApnMPwAAAAAMFMw/AAAAADL3yz8AAAAAwGvMPwAAAAD+Wsw/AAAAAARczD8AAAAAbVraPwAAAABtWto/AAAAAKRh2j8AAAAApGHaPwAAAADvUdo/AAAAAO9R2j8AAAAAjD7aPwAAAACMPto/AAAAAEgJzD8AAAAA0t/MPwAAAAC0HMw/AAAAAEZZzD8AAAAAVGW3PwAAAAABltQ/AAAAAAGW1D8AAAAAAZbUPwAAAAABltQ/AAAAAFa78z8AAAAAVrvzPwAAAABWu/M/AAAAAFa78z8AAAAAVrvzPwAAAABWu/M/AAAAAFa78z8AAAAAVrvzPwAAAABWu/M/AAAAAFa78z8AAAAAVrvzPwAAAABWu/M/AAAAwDeb8z8AAADAN5vzPwAAAMA3m/M/AAAAwDeb8z8AAADAN5vzPwAAAMA3m/M/AAAAwDeb8z8AAADAN5vzPwAAAMA3m/M/AAAAwDeb8z8AAAAAqYrUPwAAAACpitQ/AAAAAKmK1D8AAAAAqYrUPwAAAAB2wsQ/AAAAAHbCxD8AAAAAvYLUPwAAAAC9gtQ/AAAAAL2C1D8AAAAAvYLUPwAAAABcQ7c/AAAAAAg5tz8AAAAA+MTEPwAAAAD4xMQ/AAAAAOYsxT8AAAAA5izFPwAAAABW68Q/AAAAAFbrxD8AAAAA5Fa3PwAAAACoHLc/AAAAABRktz8AAAAAkAS3PwAAAAB87bc/AAAAABq2xD8AAAAAGrbEPwAAAAAGzcQ/AAAAAAbNxD8AAAAAuLHEPwAAAAC4scQ/AAAAAB921D8AAAAAH3bUPwAAAAAfdtQ/AAAAANSxxD8AAAAA1LHEPwAAAAAhdNQ/AAAAACF01D8AAAAAIXTUPwAAAADQusQ/AAAAANC6xD8AAAAAhGfUPwAAAACEZ9Q/AAAAAIRn1D8AAAAAiq7EPwAAAACKrsQ/AAAAAK111D8AAAAArXXUPwAAAACtddQ/AAAAACTGtz8AAAAAhN+3PwAAAAB82sQ/AAAAAHzaxD8AAAAAdJe3PwAAAACg/LY/AAAAABDkxD8AAAAAEOTEPwAAAIAh9uM/AAAAgCH24z8AAACAIfbjPwAAAIAh9uM/AAAAgCH24z8AAACAIfbjPwAAAIAh9uM/AAAAgCH24z8AAAAAGCu3PwAAAADgA7c/AAAAAFhDtz8AAAAAwGW3PwAAAAC4prc/AAAAgF/F4z8AAACAX8XjPwAAAIBfxeM/AAAAgF/F4z8AAACAX8XjPwAAAADkdrc/AAAAAKyRtz8AAAAABJe3PwAAAABEKLc/AAAAAIx2tz8AAAAAYgHFPwAAAABiAcU/AAAAAAbbxD8AAAAABtvEPwAAAAB2xMQ/AAAAAHbExD8AAAAAcEa3PwAAAAAwurc/AAAAACw7tz8AAAAASP62PwAAAACQ4rY/AAAAALi/xD8AAAAAuL/EPwAAAABCAMU/AAAAAEIAxT8AAAAAAsHEPwAAAAACwcQ/AAAAANOI1D8AAAAA04jUPwAAAADTiNQ/AAAAAATTxD8AAAAABNPEPwAAAACowsQ/AAAAAKjCxD8AAAAATM7EPwAAAABMzsQ/AAAAAHR31D8AAAAAdHfUPwAAAAB0d9Q/AAAAAHR31D8AAAAAFFa3PwAAAABS8MQ/AAAAAFLwxD8AAAAA+D+3PwAAAAAYGbg/AAAAACB8tz8AAAAA1PK3PwAAAACg+rc/AAAAAPwZuD8AAAAA4E+3PwAAAAB8ILg/AAAAAADRtz8AAAAAZPO3Pw==", + "dtype": "f8" + }, + "xaxis": "x5", + "y": [ + 1239.412546157837, + 1098.1104373931885, + 1154.19602394104, + 4510.21933555603, + 4494.439601898193, + 4409.020662307739, + 4393.108129501343, + 4233.517646789551, + 4269.8938846588135, + 4457.683086395264, + 4733.227014541626, + 4704.926490783691, + 4606.849193572998, + 4828.887701034546, + 4734.932899475098, + 4675.913572311401, + 6613.4092807769775, + 3440.9260749816895, + 3389.068365097046, + 3423.8274097442627, + 6610.207557678223, + 3341.8314456939697, + 3549.079656600952, + 3607.3858737945557, + 6942.271709442139, + 3715.7914638519287, + 6755.097150802612, + 3435.056209564209, + 3419.992208480835, + 6644.986629486084, + 6686.3908767700195, + 3612.8828525543213, + 6993.059873580933, + 7062.315464019775, + 7037.425994873047, + 424.75414276123047, + 1184.8924160003662, + 1211.4791870117188, + 1370.3761100769043, + 2181.6656589508057, + 1913.1779670715332, + 2177.26469039917, + 1027.8291702270508, + 975.0382900238037, + 1154.3619632720947, + 1139.9791240692139, + 1332.9744338989258, + 426.7880916595459, + 497.36762046813965, + 429.70991134643555, + 625.1053810119629, + 495.13912200927734, + 380.718469619751, + 379.32825088500977, + 502.0744800567627, + 775.7399082183838, + 501.1467933654785, + 437.1962547302246, + 498.9168643951416, + 498.19111824035645, + 376.0392665863037, + 389.0364170074463, + 518.979549407959, + 2045.6509590148926, + 2169.6372032165527, + 2079.4479846954346, + 2239.0873432159424, + 2336.2433910369873, + 2866.711139678955, + 2272.03106880188, + 2151.787757873535, + 2034.2597961425781, + 2397.1872329711914, + 2510.164260864258, + 2722.6386070251465, + 2665.2448177337646, + 1692.610263824463, + 2685.5132579803467, + 2701.889753341675, + 2564.913272857666, + 2698.924779891968, + 2916.477680206299, + 2532.0773124694824, + 2701.4191150665283, + 2740.856409072876, + 2693.565607070923, + 2673.5010147094727, + 2699.528932571411, + 2391.237258911133, + 2461.808443069458, + 2774.1546630859375, + 2639.678716659546, + 2559.1344833374023, + 2832.1125507354736, + 2632.473945617676, + 2650.6786346435547, + 2919.6181297302246, + 2901.495933532715, + 2660.068988800049, + 2682.655096054077, + 2780.21240234375, + 2692.486524581909, + 2382.648229598999, + 2701.9243240356445, + 2489.9375438690186, + 2488.4541034698486, + 2815.8211708068848, + 2655.0378799438477, + 2692.6867961883545, + 2552.3202419281006, + 2759.678602218628, + 498.3353614807129, + 670.3336238861084, + 389.0197277069092, + 759.1495513916016, + 740.8127784729004, + 386.8069648742676, + 489.14313316345215, + 396.0223197937012, + 703.5160064697266, + 665.036678314209, + 1608.3993911743164, + 1845.249891281128, + 2064.7008419036865, + 1676.7785549163818, + 860.0966930389404, + 1006.9160461425781, + 733.0417633056641, + 625.2627372741699, + 740.7782077789307, + 727.9038429260254, + 803.1458854675293, + 627.0859241485596, + 557.898759841919, + 841.2566184997559, + 517.4312591552734, + 473.0820655822754, + 847.6097583770752, + 895.5509662628174, + 987.2384071350098, + 900.2752304077148, + 2127.7647018432617, + 2153.080701828003, + 2196.354627609253, + 2169.3367958068848, + 2236.2775802612305, + 2201.300621032715, + 1854.3415069580078, + 2518.113851547241, + 2496.927499771118, + 2577.914237976074, + 2415.3976440429688, + 2548.5477447509766, + 2747.2939491271973, + 1483.9794635772705, + 2730.5068969726562, + 1442.1639442443848, + 1455.9640884399414, + 1583.616018295288, + 2946.810245513916, + 3189.6872520446777, + 1727.5981903076172, + 1769.7482109069824, + 551.626443862915, + 547.6830005645752, + 642.3606872558594, + 662.8172397613525, + 868.5297966003418, + 977.3569107055664, + 676.8646240234375, + 613.4209632873535, + 672.7337837219238, + 799.5762825012207, + 266.8261528015137, + 315.7384395599365, + 511.5017890930176, + 528.6984443664551, + 375.00500679016113, + 850.9516716003418, + 680.3216934204102, + 672.6996898651123, + 357.9421043395996, + 277.3890495300293, + 228.87945175170898, + 226.73726081848145, + 258.97979736328125, + 601.8943786621094, + 657.5629711151123, + 356.18019104003906, + 862.1442317962646, + 616.5914535522461, + 416.3649082183838, + 545.1583862304688, + 876.1696815490723, + 648.3185291290283, + 719.8326587677002, + 668.8342094421387, + 534.4247817993164, + 782.4859619140625, + 681.199312210083, + 594.0918922424316, + 669.5401668548584, + 666.9857501983643, + 558.9003562927246, + 655.2984714508057, + 695.7080364227295, + 667.9730415344238, + 668.9703464508057, + 672.4808216094971, + 796.9186305999756, + 542.0253276824951, + 342.21959114074707, + 535.9678268432617, + 559.4592094421387, + 619.7400093078613, + 217.13566780090332, + 521.0361480712891, + 521.1203098297119, + 1149.1453647613525, + 1168.1902408599854, + 1225.0967025756836, + 1197.9188919067383, + 1209.2185020446777, + 1357.3546409606934, + 1345.548152923584, + 1351.522445678711, + 882.30299949646, + 283.60676765441895, + 226.25088691711426, + 324.0830898284912, + 373.7754821777344, + 1064.7220611572266, + 1050.7266521453857, + 1130.0702095031738, + 1247.443437576294, + 1261.1429691314697, + 1399.1074562072754, + 358.7038516998291, + 487.48278617858887, + 223.94704818725586, + 335.30545234680176, + 315.6306743621826, + 431.44702911376953, + 626.7228126525879, + 717.0486450195312, + 403.32674980163574, + 460.1702690124512, + 279.96277809143066, + 411.2522602081299, + 329.72264289855957, + 607.0575714111328, + 370.41711807250977, + 571.0227489471436, + 439.9096965789795, + 379.0273666381836, + 399.1570472717285, + 642.11106300354, + 695.8215236663818, + 704.7250270843506, + 694.7691440582275, + 874.5927810668945, + 416.2912368774414, + 405.5216312408447, + 447.9658603668213, + 400.30455589294434, + 463.5791778564453, + 484.62605476379395, + 563.3785724639893, + 544.0158843994141, + 706.6855430603027, + 720.8178043365479, + 594.7082042694092, + 425.34947395324707, + 404.01411056518555, + 483.3545684814453, + 621.532678604126, + 317.13080406188965, + 430.9539794921875, + 217.4384593963623, + 315.9356117248535, + 341.27044677734375, + 315.32979011535645, + 305.6526184082031, + 313.92979621887207 + ], + "yaxis": "y5" + }, + { + "hovertemplate": "Output Tokens=100 output tokens
Concurrency=32
Server TTFT (s)=%{x}
TEE Network Latency (ms)=%{y}", + "legendgroup": "100 output tokens", + "marker": { + "color": "#636efa", + "opacity": 0.55, + "symbol": "circle" + }, + "mode": "markers", + "name": "100 output tokens", + "showlegend": false, + "type": "scattergl", + "x": { + "bdata": "AAAAAAw6tz8AAADApIfzPwAAAMCkh/M/AAAAwKSH8z8AAADApIfzPwAAAMCkh/M/AAAAwKSH8z8AAADApIfzPwAAAMCkh/M/AAAAwKSH8z8AAADApIfzPwAAAMDNmfM/AAAAwM2Z8z8AAADAzZnzPwAAAMDNmfM/AAAAwM2Z8z8AAADAzZnzPwAAAMDNmfM/AAAAwM2Z8z8AAADAzZnzPwAAAMDNmfM/AAAAwM2Z8z8AAAAA7G63PwAAAADSysQ/AAAAANLKxD8AAAAAWq7EPwAAAABarsQ/AAAAAJyN1D8AAAAAnI3UPwAAAACcjdQ/AAAAABTUxD8AAAAAFNTEPwAAAABit8Q/AAAAAGK3xD8AAAAA4MrEPwAAAADgysQ/AAAAALbXxD8AAAAAttfEPwAAAADq3sQ/AAAAAOrexD8AAAAAoMHEPwAAAACgwcQ/AAAAAPbIxD8AAAAA9sjEPwAAAACEnLg/AAAAACCgtz8AAAAAMKW3PwAAAABIsbc/AAAAAFzNtz8AAAAAL5zUPwAAAAAvnNQ/AAAAAC+c1D8AAAAAaLG3PwAAAABc27c/AAAAAGQVtz8AAAAAsFu3PwAAAACyBMU/AAAAALIExT8AAAAAUMq3PwAAAAAgarc/AAAAANykxD8AAAAA3KTEPwAAAAA42rc/AAAAACQ3uD8AAAAAzO22PwAAAAAMWbc/AAAAAKj6tj8AAADAw6rzPwAAAMDDqvM/AAAAwMOq8z8AAADAw6rzPwAAAMDDqvM/AAAAwMOq8z8AAADAw6rzPwAAAMDDqvM/AAAAwMOq8z8AAADAw6rzPwAAAMDDqvM/AAAAwMOq8z8AAADAw6rzPwAAAMDDqvM/AAAAwMOq8z8AAADAw6rzPwAAAACG0uM/AAAAAIbS4z8AAAAAhtLjPwAAAACG0uM/AAAAAIbS4z8AAAAAhtLjPwAAAAD4xrc/AAAAwGuO8z8AAADAa47zPwAAAMBrjvM/AAAAwGuO8z8AAADAa47zPwAAAMBrjvM/AAAAwGuO8z8AAADAa47zPwAAAMBrjvM/AAAAwGuO8z8AAAAAJbPzPwAAAAAls/M/AAAAACWz8z8AAAAAJbPzPwAAAAAls/M/AAAAACWz8z8AAAAAJbPzPwAAAAAls/M/AAAAACWz8z8AAAAAJbPzPwAAAAAls/M/AAAAACWz8z8AAAAAhuLjPwAAAACG4uM/AAAAAIbi4z8AAAAAhuLjPwAAAACG4uM/AAAAAIbi4z8AAAAAdEm3PwAAAAB8J7c/AAAAADwftz8AAAAABOi2PwAAAABsCLg/AAAAgJDX4z8AAACAkNfjPwAAAICQ1+M/AAAAgJDX4z8AAACAkNfjPwAAAABm58Q/AAAAAGbnxD8AAAAA0EW3PwAAAADoJrc/AAAAAHhdtz8AAAAA3Hu3PwAAAAAooLc/AAAAACTHtz8AAAAAfEm4PwAAAADQU7g/AAAAAFQXuD8AAAAAENfEPwAAAAAQ18Q/AAAAANFv1D8AAAAA0W/UPwAAAADRb9Q/AAAAANFv1D8AAAAA+KzEPwAAAAD4rMQ/AAAAAJzZ4z8AAAAAnNnjPwAAAACc2eM/AAAAAJzZ4z8AAAAAnNnjPwAAAACIi7c/AAAAAORAtz8AAAAAvEy4PwAAAADI3Lc/AAAAAJ2L1D8AAAAAnYvUPwAAAACdi9Q/AAAAAJ2L1D8AAAAAcH3UPwAAAABwfdQ/AAAAAHB91D8AAAAAKo/UPwAAAAAqj9Q/AAAAACqP1D8AAAAAKo/UPwAAAACMYdQ/AAAAAIxh1D8AAAAAjGHUPwAAAAAIbrc/AAAAAMhWuD8AAAAAxtbEPwAAAADG1sQ/AAAAACiptz8AAAAAWOTEPwAAAABY5MQ/AAAAAPhotz8AAAAAEHq4PwAAAAA8d7g/AAAAAIAmuD8AAAAA+M63PwAAAACc97c/AAAAAIR9tz8AAAAAfOK3PwAAAABS68Q/AAAAAFLrxD8AAACAutrjPwAAAIC62uM/AAAAgLra4z8AAACAutrjPwAAAIC62uM/AAAAAPA5tz8AAAAASCm5PwAAAACAXbc/AAAAAHRTtz8AAAAA6CW4PwAAAADwXrc/AAAAABxjtz8AAAAAaJS3PwAAAADM4MQ/AAAAAMzgxD8AAAAA6BW3PwAAAAAsQbc/AAAAAJrlxD8AAAAAmuXEPwAAAACLbtQ/AAAAAItu1D8AAAAAi27UPwAAAABgrMQ/AAAAAGCsxD8AAAAAqHTUPwAAAACodNQ/AAAAAKh01D8AAAAAu4rUPwAAAAC7itQ/AAAAALuK1D8AAAAA5Da3PwAAAAC0ubc/AAAAAFBjtz8AAAAAZKO3PwAAAABw17c/AAAAACDNtz8AAAAAsF63PwAAAACLetQ/AAAAAIt61D8AAAAAi3rUPwAAAIBD2+M/AAAAgEPb4z8AAACAQ9vjPwAAAIBD2+M/AAAAgEPb4z8AAACAQ9vjPwAAAIBD2+M/AAAAABGE1D8AAAAAEYTUPwAAAAARhNQ/AAAAAFfY4z8AAAAAV9jjPwAAAABX2OM/AAAAAFfY4z8AAAAAV9jjPwAAAABX2OM/AAAAAFfY4z8AAAAAV6PUPwAAAABXo9Q/AAAAAFej1D8AAAAAAt/jPwAAAAAC3+M/AAAAAALf4z8AAAAAAt/jPwAAAAAC3+M/AAAAAA6wxD8AAAAADrDEPwAAAACO5MQ/AAAAAI7kxD8AAAAAmGy3PwAAAACg9rY/AAAAACydtz8AAAAANAW4PwAAAAD49bc/AAAAAOwstz8AAAAAQCq3PwAAAAA2Asw/AAAAwCvDCEAAAADAK8MIQAAAAMArwwhAAAAAwCvDCEAAAADAK8MIQAAAAMArwwhAAAAAwCvDCEAAAADAK8MIQAAAAMArwwhAAAAAwCvDCEAAAADAK8MIQAAAAMArwwhAAAAAwCvDCEAAAADAK8MIQAAAAMArwwhAAAAAwCvDCEAAAADAK8MIQAAAAEB+twhAAAAAQH63CEAAAABAfrcIQAAAAEB+twhAAAAAQH63CEAAAABAfrcIQAAAAEB+twhAAAAAQH63CEAAAABAfrcIQAAAAEB+twhAAAAAQH63CEAAAABAfrcIQAAAAEB+twhAAAAAQH63CEAAAABAfrcIQAAAAAC4vQhAAAAAALi9CEAAAAAAuL0IQAAAAAC4vQhAAAAAALi9CEAAAAAAuL0IQAAAAAC4vQhAAAAAALi9CEAAAAAAuL0IQAAAAACgGMw/AAAAgD106T8AAACAPXTpPwAAAIA9dOk/AAAAgD106T8AAAAA/LXMPwAAAAC4EMw/AAAAABYEzD8AAAAAzF/aPwAAAADMX9o/AAAAABdV2j8AAAAAF1XaPwAAAADsUto/AAAAAOxS2j8AAAAAo17aPwAAAACjXto/AAAAADtl6T8AAAAAO2XpPwAAAAA7Zek/AAAAAItn2j8AAAAAi2faPwAAAAA4Scw/AAAAACAGzD8AAAAAepXMPwAAAADAvdo/AAAAAMC92j8AAACAwF/pPwAAAIDAX+k/AAAAgMBf6T8AAAAAD1/aPwAAAAAPX9o/AAAAgKpg6T8AAACAqmDpPwAAAICqYOk/AAAAAKQ+2j8AAAAApD7aPwAAAADvZto/AAAAAO9m2j8AAAAAFmXMPwAAAABmksw/AAAAAL9k2j8AAAAAv2TaPwAAAAAKCvk/AAAAAAoK+T8AAAAACgr5PwAAAAAKCvk/AAAAAAoK+T8AAAAACgr5PwAAAABETNo/AAAAAERM2j8AAACAyvP4PwAAAIDK8/g/AAAAgMrz+D8AAACAyvP4PwAAAIDK8/g/AAAAgMrz+D8AAAAAE2naPwAAAAATado/AAAAwLX2+D8AAADAtfb4PwAAAMC19vg/AAAAwLX2+D8AAADAtfb4PwAAAMC19vg/AAAAAAoJzD8AAAAACB7MPwAAAACgLcw/AAAAAIjsyz8AAAAA9z3aPwAAAAD3Pdo/AAAAAB79yz8AAAAARhvMPwAAAACsUNo/AAAAAKxQ2j8AAAAAJvDLPwAAAAC1XNo/AAAAALVc2j8AAAAAyPbLPwAAAAA+UMw/AAAAAJixzD8AAAAAwAnMPwAAAAD0D8w/AAAAANb8yz8AAAAA2P7MPwAAAICnZuk/AAAAgKdm6T8AAACAp2bpPwAAAMBLuQhAAAAAwEu5CEAAAADAS7kIQAAAAMBLuQhAAAAAwEu5CEAAAADAS7kIQAAAAMBLuQhAAAAAwEu5CEAAAADAS7kIQAAAAMBLuQhAAAAAwEu5CEAAAABgTc8IQAAAAGBNzwhAAAAAYE3PCEAAAABgTc8IQAAAAGBNzwhAAAAAYE3PCEAAAABgTc8IQAAAAGBNzwhAAAAAYE3PCEAAAABgTc8IQAAAAGBNzwhAAAAAYE3PCEAAAABgTc8IQAAAAGBNzwhAAAAAoCLSCEAAAACgItIIQAAAAKAi0ghAAAAAoCLSCEAAAACgItIIQAAAAKAi0ghAAAAAoCLSCEAAAACgItIIQAAAAKAi0ghAAAAAoCLSCEAAAACgItIIQAAAAKAi0ghAAAAAoCLSCEAAAACgItIIQAAAAMDe+fg/AAAAwN75+D8AAADA3vn4PwAAAMDe+fg/AAAAwN75+D8AAADA3vn4PwAAAMDe+fg/AAAAwN75+D8AAAAArOrLPwAAAAD0Gsw/AAAAAIA9zD8AAAAA0PnLPwAAAIDYdek/AAAAgNh16T8AAACA2HXpPwAAAED+5/g/AAAAQP7n+D8AAABA/uf4PwAAAED+5/g/AAAAQP7n+D8AAABA/uf4PwAAAED+5/g/AAAAgHHk+D8AAACAceT4PwAAAIBx5Pg/AAAAgHHk+D8AAACAceT4PwAAAEAl+fg/AAAAQCX5+D8AAABAJfn4PwAAAEAl+fg/AAAAQCX5+D8AAABAJfn4PwAAAEAl+fg/AAAAQCX5+D8AAACAO/v4PwAAAIA7+/g/AAAAgDv7+D8AAACAO/v4PwAAAIA7+/g/AAAAgDv7+D8AAACAO/v4PwAAAIA7+/g/AAAAIBTPCEAAAAAgFM8IQAAAACAUzwhAAAAAIBTPCEAAAAAgFM8IQAAAACAUzwhAAAAAIBTPCEAAAAAgFM8IQAAAACAUzwhAAAAAIBTPCEAAAAAgFM8IQAAAACAUzwhAAAAAIBTPCEAAAAAgFM8IQAAAAIDsywhAAAAAgOzLCEAAAACA7MsIQAAAAIDsywhAAAAAgOzLCEAAAACA7MsIQAAAAIDsywhAAAAAgOzLCEAAAACA7MsIQAAAAIDsywhAAAAAgOzLCEAAAACA7MsIQAAAAIDsywhAAAAAADtk2j8AAAAAO2TaPwAAAAA5dOk/AAAAADl06T8AAAAAOXTpPwAAAAD+E8w/AAAAACtn2j8AAAAAK2faPwAAAAD0Vto/AAAAAPRW2j8AAADAlP/4PwAAAMCU//g/AAAAwJT/+D8AAADAlP/4PwAAAMCU//g/AAAAACTvyz8AAAAAVGjMPwAAAACgYcw/", + "dtype": "f8" + }, + "xaxis": "x6", + "y": [ + 482.73324966430664, + 1726.9997596740723, + 1679.137945175171, + 1741.5425777435303, + 1784.825325012207, + 1918.7912940979004, + 1976.109266281128, + 1894.8042392730713, + 2069.1187381744385, + 2034.0197086334229, + 1928.3008575439453, + 3291.5968894958496, + 1484.0905666351318, + 1464.5373821258545, + 1456.0272693634033, + 3463.222026824951, + 1817.9678916931152, + 3656.4908027648926, + 3611.595630645752, + 1750.9560585021973, + 3583.130121231079, + 3610.407590866089, + 1756.8533420562744, + 415.65823554992676, + 404.6216011047363, + 414.9603843688965, + 481.9152355194092, + 873.5880851745605, + 886.1498832702637, + 988.0516529083252, + 406.2838554382324, + 423.86674880981445, + 563.8580322265625, + 410.4423522949219, + 396.7149257659912, + 417.59634017944336, + 397.58944511413574, + 415.9426689147949, + 380.2046775817871, + 467.97776222229004, + 387.0277404785156, + 473.2825756072998, + 383.57996940612793, + 584.7291946411133, + 422.17421531677246, + 267.73786544799805, + 320.56736946105957, + 309.0212345123291, + 322.91674613952637, + 460.98804473876953, + 712.8572463989258, + 602.4959087371826, + 589.5133018493652, + 455.71422576904297, + 353.23619842529297, + 723.2613563537598, + 453.34506034851074, + 517.3611640930176, + 304.7606945037842, + 906.4605236053467, + 448.5430717468262, + 307.7218532562256, + 530.5299758911133, + 556.4908981323242, + 268.7416076660156, + 429.28147315979004, + 537.9979610443115, + 1734.543800354004, + 1806.6911697387695, + 1758.4714889526367, + 1791.8462753295898, + 1800.8501529693604, + 1785.9716415405273, + 1682.419776916504, + 1698.291540145874, + 1676.1221885681152, + 1758.772373199463, + 1827.8141021728516, + 1925.7335662841797, + 2037.3508930206299, + 2003.502607345581, + 1996.8321323394775, + 1961.399793624878, + 2735.628366470337, + 2263.075828552246, + 1049.4024753570557, + 1864.886999130249, + 1873.3885288238525, + 2917.8829193115234, + 467.29159355163574, + 1675.0926971435547, + 1710.1795673370361, + 2014.1618251800537, + 1938.1074905395508, + 1930.689811706543, + 1984.037160873413, + 2001.4753341674805, + 1968.2741165161133, + 1954.6713829040527, + 1978.7096977233887, + 2856.524705886841, + 2354.2449474334717, + 2338.531494140625, + 2333.6551189422607, + 2326.9147872924805, + 2451.0066509246826, + 1598.3796119689941, + 3042.510509490967, + 3073.3706951141357, + 2634.2592239379883, + 3019.5863246917725, + 3144.7439193725586, + 2344.986915588379, + 2428.463935852051, + 2463.794231414795, + 2491.47367477417, + 2503.485918045044, + 2676.701545715332, + 354.0835380554199, + 352.008581161499, + 315.76061248779297, + 215.69561958312988, + 375.213623046875, + 1017.9386138916016, + 1008.2590579986572, + 1212.226152420044, + 1204.3251991271973, + 1175.4143238067627, + 471.5452194213867, + 460.1318836212158, + 358.9317798614502, + 317.4309730529785, + 234.03692245483398, + 236.60588264465332, + 312.72172927856445, + 314.29219245910645, + 335.79182624816895, + 515.7625675201416, + 315.457820892334, + 427.98471450805664, + 440.3653144836426, + 791.7900085449219, + 787.2498035430908, + 775.4611968994141, + 685.4248046875, + 424.03316497802734, + 549.0872859954834, + 820.1210498809814, + 830.8839797973633, + 843.7769412994385, + 911.2787246704102, + 966.5112495422363, + 1062.0970726013184, + 283.2465171813965, + 313.94124031066895, + 487.3213768005371, + 840.7633304595947, + 453.7203311920166, + 836.0018730163574, + 972.0990657806396, + 855.0543785095215, + 726.4978885650635, + 873.1939792633057, + 735.9850406646729, + 608.1836223602295, + 799.4647026062012, + 790.1349067687988, + 664.1073226928711, + 800.2359867095947, + 783.0784320831299, + 582.0164680480957, + 358.03723335266113, + 422.2700595855713, + 543.8807010650635, + 676.6536235809326, + 307.97743797302246, + 342.8916931152344, + 318.53389739990234, + 426.35655403137207, + 321.9163417816162, + 426.54871940612793, + 262.2802257537842, + 405.869722366333, + 321.2127685546875, + 546.3495254516602, + 500.55408477783203, + 461.2467288970947, + 1185.2812767028809, + 1327.0978927612305, + 1302.1149635314941, + 1341.5653705596924, + 1325.1399993896484, + 601.5951633453369, + 269.8843479156494, + 355.1325798034668, + 313.48586082458496, + 228.21927070617676, + 311.8786811828613, + 219.19965744018555, + 339.04099464416504, + 560.7576370239258, + 603.5788059234619, + 713.8118743896484, + 217.26512908935547, + 401.31330490112305, + 397.7022171020508, + 658.4727764129639, + 772.0780372619629, + 634.225606918335, + 572.1738338470459, + 672.4536418914795, + 543.5421466827393, + 584.5539569854736, + 724.6356010437012, + 742.6893711090088, + 736.3653182983398, + 774.4426727294922, + 558.3000183105469, + 780.8732986450195, + 442.9647922515869, + 227.0979881286621, + 1328.960657119751, + 462.91351318359375, + 230.2377223968506, + 601.712703704834, + 651.2887477874756, + 643.5315608978271, + 1319.5850849151611, + 1375.1699924468994, + 1385.467529296875, + 1359.4245910644531, + 1399.8386859893799, + 1549.3440628051758, + 1592.1318531036377, + 1224.910020828247, + 1152.4770259857178, + 1218.5232639312744, + 1198.828935623169, + 1228.7378311157227, + 1284.3677997589111, + 1142.5914764404297, + 1402.6024341583252, + 1380.9890747070312, + 1206.150770187378, + 1232.3999404907227, + 1229.856252670288, + 1365.2706146240234, + 1219.0754413604736, + 1159.3661308288574, + 1333.1193923950195, + 1190.727949142456, + 1212.8386497497559, + 941.8189525604248, + 1054.5659065246582, + 505.4953098297119, + 618.1459426879883, + 436.7985725402832, + 441.4026737213135, + 339.5037651062012, + 236.96517944335938, + 463.34123611450195, + 265.8212184906006, + 320.92738151550293, + 1034.386157989502, + 4480.281591415405, + 4369.774341583252, + 4531.80193901062, + 3937.1652603149414, + 4414.148807525635, + 4481.9934368133545, + 4327.7153968811035, + 3925.708770751953, + 3998.796224594116, + 4397.297620773315, + 4229.923963546753, + 4100.162982940674, + 3975.522041320801, + 4253.392457962036, + 4270.314455032349, + 4123.145341873169, + 4179.2566776275635, + 7517.133474349976, + 7672.736167907715, + 7383.291721343994, + 7544.048547744751, + 7314.475774765015, + 7585.894346237183, + 7289.103269577026, + 6522.074460983276, + 7615.905046463013, + 7790.143013000488, + 8062.562704086304, + 7817.646265029907, + 7667.9368019104, + 7521.664619445801, + 7750.573635101318, + 6655.569314956665, + 6597.560882568359, + 6643.355369567871, + 6585.390090942383, + 6558.134317398071, + 6758.575201034546, + 6858.905792236328, + 6881.6680908203125, + 6915.45844078064, + 611.4587783813477, + 1606.0163974761963, + 1587.0656967163086, + 1573.9154815673828, + 1550.934076309204, + 402.62794494628906, + 658.4103107452393, + 500.11420249938965, + 803.8661479949951, + 849.4937419891357, + 1294.830083847046, + 840.1429653167725, + 830.9252262115479, + 855.5030822753906, + 853.2676696777344, + 834.8178863525391, + 1584.779977798462, + 1240.304946899414, + 1260.011911392212, + 1311.3229274749756, + 1385.0209712982178, + 814.6302700042725, + 422.74999618530273, + 835.2420330047607, + 805.4568767547607, + 660.8624458312988, + 1638.404369354248, + 1114.7046089172363, + 1147.8257179260254, + 1102.9658317565918, + 1244.4465160369873, + 1203.3743858337402, + 1226.412296295166, + 1386.3070011138916, + 1266.7036056518555, + 1399.430274963379, + 762.5908851623535, + 1026.371955871582, + 802.5310039520264, + 456.0267925262451, + 825.4556655883789, + 673.7258434295654, + 2326.2133598327637, + 2387.22825050354, + 2460.2975845336914, + 2675.1551628112793, + 2616.375684738159, + 2696.7971324920654, + 2185.506820678711, + 2306.657552719116, + 2353.7075519561768, + 2083.6634635925293, + 2310.546398162842, + 2060.9290599823, + 2033.8373184204102, + 2380.5458545684814, + 2178.156852722168, + 2087.0141983032227, + 2328.836679458618, + 2396.2433338165283, + 2249.4382858276367, + 2524.0232944488525, + 2585.824966430664, + 2646.712064743042, + 392.4717903137207, + 387.8467082977295, + 378.3085346221924, + 440.39058685302734, + 1065.6664371490479, + 1005.3837299346924, + 613.6965751647949, + 377.32481956481934, + 796.6985702514648, + 821.509838104248, + 687.781572341919, + 579.1747570037842, + 645.6108093261719, + 637.4802589416504, + 500.7786750793457, + 737.0467185974121, + 381.15382194519043, + 382.7168941497803, + 494.74525451660156, + 616.0871982574463, + 1189.4786357879639, + 1323.209524154663, + 1301.6393184661865, + 4420.788288116455, + 4360.412120819092, + 4558.938264846802, + 4544.718265533447, + 4998.257160186768, + 4832.302808761597, + 4814.697265625, + 4956.68363571167, + 4751.582145690918, + 4943.424463272095, + 4995.939254760742, + 6625.908613204956, + 6608.927965164185, + 4120.7263469696045, + 3389.657735824585, + 4091.665267944336, + 4110.085487365723, + 7021.281719207764, + 4526.738405227661, + 4420.628547668457, + 4571.8278884887695, + 4439.395189285278, + 4523.528099060059, + 4564.960241317749, + 3830.3494453430176, + 7075.363636016846, + 6717.904567718506, + 6629.901647567749, + 3362.6227378845215, + 3464.735746383667, + 7204.150199890137, + 6805.015325546265, + 7054.604291915894, + 7044.239282608032, + 7099.900722503662, + 3746.065378189087, + 3798.0713844299316, + 3792.0377254486084, + 7023.8988399505615, + 5493.203639984131, + 5162.021160125732, + 5074.393510818481, + 5177.224159240723, + 5102.644920349121, + 5139.693975448608, + 5365.064859390259, + 5329.327344894409, + 542.6657199859619, + 427.51455307006836, + 376.68299674987793, + 511.7475986480713, + 1269.1423892974854, + 1360.351324081421, + 1450.7825374603271, + 3071.65265083313, + 3038.6600494384766, + 3022.428274154663, + 2647.7770805358887, + 2631.192684173584, + 2829.9319744110107, + 3339.399576187134, + 1855.1523685455322, + 1966.3975238800049, + 1906.3925743103027, + 2172.2919940948486, + 2118.680238723755, + 3726.6557216644287, + 3695.0607299804688, + 3815.4098987579346, + 1762.7131938934326, + 3854.5215129852295, + 3980.3102016448975, + 4016.2041187286377, + 4159.208059310913, + 3582.115650177002, + 3337.8801345825195, + 3163.4654998779297, + 3357.9068183898926, + 3575.882911682129, + 3887.1703147888184, + 2926.0451793670654, + 3429.0151596069336, + 5093.873023986816, + 4867.634057998657, + 4486.89079284668, + 4561.204195022583, + 4542.975664138794, + 4897.750377655029, + 4508.273124694824, + 4769.047498703003, + 5419.151306152344, + 5481.850147247314, + 5206.417560577393, + 5522.964000701904, + 4927.35743522644, + 4825.346231460571, + 6897.190570831299, + 6577.100515365601, + 3368.516683578491, + 6615.316152572632, + 3452.268123626709, + 6870.916843414307, + 7243.492841720581, + 3789.414882659912, + 3775.330066680908, + 7195.594310760498, + 3760.668992996216, + 7220.87836265564, + 6971.416473388672, + 3998.9020824432373, + 4095.806121826172, + 1338.8402462005615, + 1396.8803882598877, + 1375.5769729614258, + 1667.27614402771, + 922.8370189666748, + 692.6796436309814, + 639.0292644500732, + 774.5189666748047, + 2428.3852577209473, + 2351.285219192505, + 2512.7768516540527, + 2543.450355529785, + 2581.853151321411, + 2206.583261489868, + 545.6552505493164, + 786.3354682922363 + ], + "yaxis": "y6" + } + ], + "layout": { + "annotations": [ + { + "font": {}, + "showarrow": false, + "text": "Concurrency=1", + "x": 0.075, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=3", + "x": 0.24499999999999997, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=5", + "x": 0.415, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=8", + "x": 0.585, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=16", + "x": 0.7549999999999999, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + }, + { + "font": {}, + "showarrow": false, + "text": "Concurrency=32", + "x": 0.925, + "xanchor": "center", + "xref": "paper", + "y": 1, + "yanchor": "bottom", + "yref": "paper" + } + ], + "height": 420, + "legend": { + "title": { + "text": "Output Tokens" + }, + "tracegroupgap": 0 + }, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "white", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "#C8D4E3", + "linecolor": "#C8D4E3", + "minorgridcolor": "#C8D4E3", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermap": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermap" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "white", + "showlakes": true, + "showland": true, + "subunitcolor": "#C8D4E3" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "white", + "polar": { + "angularaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + }, + "bgcolor": "white", + "radialaxis": { + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "yaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + }, + "zaxis": { + "backgroundcolor": "white", + "gridcolor": "#DFE8F3", + "gridwidth": 2, + "linecolor": "#EBF0F8", + "showbackground": true, + "ticks": "", + "zerolinecolor": "#EBF0F8" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "baxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + }, + "bgcolor": "white", + "caxis": { + "gridcolor": "#DFE8F3", + "linecolor": "#A2B1C6", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "#EBF0F8", + "linecolor": "#EBF0F8", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "#EBF0F8", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Per-Request: TEE Network Latency vs Server TTFT — Encrypted Multi Run
Shows how network latency varies independently from server TTFT. A flat horizontal spread would indicate network latency is independent of server load." + }, + "width": 1400, + "xaxis": { + "anchor": "y", + "domain": [ + 0, + 0.15 + ], + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis2": { + "anchor": "y2", + "domain": [ + 0.16999999999999998, + 0.31999999999999995 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0.33999999999999997, + 0.49 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.51, + 0.66 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis5": { + "anchor": "y5", + "domain": [ + 0.6799999999999999, + 0.83 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "xaxis6": { + "anchor": "y6", + "domain": [ + 0.85, + 1 + ], + "matches": "x", + "title": { + "text": "Server TTFT (s)" + } + }, + "yaxis": { + "anchor": "x", + "domain": [ + 0, + 1 + ], + "title": { + "text": "TEE Network Latency (ms)" + } + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis3": { + "anchor": "x3", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis4": { + "anchor": "x4", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis5": { + "anchor": "x5", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + }, + "yaxis6": { + "anchor": "x6", + "domain": [ + 0, + 1 + ], + "matches": "y", + "showticklabels": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Per-request: TEE network latency vs server TTFT (encrypted multi run only)\n", + "df_enc_ind = df_individual[\n", + " (df_individual['label'] == 'Encrypted') &\n", + " (df_individual['run_type'] == 'Multi Run (10x)') &\n", + " (~df_individual['is_error']) &\n", + " (df_individual['server_network_latency_ms'].notna())\n", + "].copy()\n", + "\n", + "fig = px.scatter(\n", + " df_enc_ind,\n", + " x='server_ttft_s',\n", + " y='server_network_latency_ms',\n", + " color='out_tokens_label',\n", + " facet_col='concurrency_str',\n", + " opacity=0.55,\n", + " category_orders={'concurrency_str': CONC_STR},\n", + " labels={\n", + " 'server_ttft_s': 'Server TTFT (s)',\n", + " 'server_network_latency_ms': 'TEE Network Latency (ms)',\n", + " 'out_tokens_label': 'Output Tokens',\n", + " 'concurrency_str': 'Concurrency',\n", + " },\n", + " title=(\n", + " 'Per-Request: TEE Network Latency vs Server TTFT — Encrypted Multi Run
'\n", + " 'Shows how network latency varies independently from server TTFT. '\n", + " 'A flat horizontal spread would indicate network latency is independent of server load.'\n", + " ),\n", + ")\n", + "fig.update_layout(height=420, width=1400, template='plotly_white')\n", + "fig.show()" + ] }, { "cell_type": "markdown", @@ -237,11 +26304,87 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 42, "id": "cell-summary-table", "metadata": {}, - "outputs": [], - "source": "DIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\nALL_METRICS = [\n ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n ('server_end_to_end_latency_s_p50', 'Server E2E p50 (s)'),\n ('client_ttft_s_p50', 'Client TTFT p50 (s)'),\n ('client_end_to_end_latency_s_p50', 'Client E2E p50 (s)'),\n ('client_output_token_per_s_p50', 'Client Tok/s p50'),\n ('client_total_output_throughput', 'Total Throughput (tok/s)'),\n ('num_completed_requests_per_min', 'Req / min'),\n ('error_rate_pct', 'Error Rate (%)'),\n]\n\ndf_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\ndf_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n\nrows = []\nfor col, label in ALL_METRICS:\n if col not in df_enc_s.columns:\n continue\n for idx in df_enc_s.index:\n if idx not in df_plain_s.index:\n continue\n enc_v = df_enc_s.loc[idx, col]\n plain_v = df_plain_s.loc[idx, col]\n if pd.isna(enc_v) and pd.isna(plain_v):\n continue\n delta = enc_v - plain_v if pd.notna(enc_v) and pd.notna(plain_v) else np.nan\n pct_chg = delta / plain_v * 100 if pd.notna(delta) and plain_v != 0 else np.nan\n rows.append({\n 'Metric': label,\n 'Input Tokens': idx[0],\n 'Output Tokens': idx[1],\n 'Concurrency': idx[2],\n 'Non-Encrypted': plain_v,\n 'Encrypted': enc_v,\n 'Delta': delta,\n '% Change': pct_chg,\n })\n\ndf_summary = pd.DataFrame(rows).sort_values(\n ['Metric', 'Input Tokens', 'Concurrency']\n)\n\ndef _pct_color(val):\n if pd.isna(val): return ''\n if val > 100: return 'background-color: #ff6666'\n if val > 50: return 'background-color: #ffaaaa'\n if val > 20: return 'background-color: #ffd8aa'\n if val > 0: return 'background-color: #fffacc'\n if val < -20: return 'background-color: #aaffaa'\n return ''\n\ndf_summary.style \\\n .applymap(_pct_color, subset=['% Change']) \\\n .format({\n 'Non-Encrypted': '{:.3f}',\n 'Encrypted': '{:.3f}',\n 'Delta': '{:+.3f}',\n '% Change': '{:+.1f}%',\n }, na_rep='—')" + "outputs": [ + { + "ename": "ValueError", + "evalue": "The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", + "\u001b[32m/var/folders/g3/mcw1yd_565l486ztq80gf9kw0000gp/T/ipykernel_95595/3116414831.py\u001b[39m in \u001b[36m?\u001b[39m\u001b[34m()\u001b[39m\n\u001b[32m 23\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m idx \u001b[38;5;28;01mnot\u001b[39;00m \u001b[38;5;28;01min\u001b[39;00m df_plain_s.index:\n\u001b[32m 24\u001b[39m \u001b[38;5;28;01mcontinue\u001b[39;00m\n\u001b[32m 25\u001b[39m enc_v = df_enc_s.loc[idx, col]\n\u001b[32m 26\u001b[39m plain_v = df_plain_s.loc[idx, col]\n\u001b[32m---> \u001b[39m\u001b[32m27\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m pd.isna(enc_v) \u001b[38;5;28;01mand\u001b[39;00m pd.isna(plain_v):\n\u001b[32m 28\u001b[39m \u001b[38;5;28;01mcontinue\u001b[39;00m\n\u001b[32m 29\u001b[39m delta = enc_v - plain_v \u001b[38;5;28;01mif\u001b[39;00m pd.notna(enc_v) \u001b[38;5;28;01mand\u001b[39;00m pd.notna(plain_v) \u001b[38;5;28;01melse\u001b[39;00m np.nan\n\u001b[32m 30\u001b[39m pct_chg = delta / plain_v * \u001b[32m100\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m pd.notna(delta) \u001b[38;5;28;01mand\u001b[39;00m plain_v != \u001b[32m0\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m np.nan\n", + "\u001b[32m~/github_repos/ai-starter-kit_copy/benchmarking/.venv/lib/python3.11/site-packages/pandas/core/generic.py\u001b[39m in \u001b[36m?\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 1525\u001b[39m @final\n\u001b[32m 1526\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m __nonzero__(self) -> NoReturn:\n\u001b[32m-> \u001b[39m\u001b[32m1527\u001b[39m raise ValueError(\n\u001b[32m 1528\u001b[39m \u001b[33mf\"The truth value of a {type(self).__name__} is ambiguous. \"\u001b[39m\n\u001b[32m 1529\u001b[39m \u001b[33m\"Use a.empty, a.bool(), a.item(), a.any() or a.all().\"\u001b[39m\n\u001b[32m 1530\u001b[39m )\n", + "\u001b[31mValueError\u001b[39m: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()." + ] + } + ], + "source": [ + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "ALL_METRICS = [\n", + " ('server_ttft_s_p50', 'Server TTFT p50 (s)'),\n", + " ('server_output_token_per_s_p50', 'Server Tok/s p50'),\n", + " ('server_end_to_end_latency_s_p50', 'Server E2E p50 (s)'),\n", + " ('client_ttft_s_p50', 'Client TTFT p50 (s)'),\n", + " ('client_end_to_end_latency_s_p50', 'Client E2E p50 (s)'),\n", + " ('client_output_token_per_s_p50', 'Client Tok/s p50'),\n", + " ('client_total_output_throughput', 'Total Throughput (tok/s)'),\n", + " ('num_completed_requests_per_min', 'Req / min'),\n", + " ('error_rate_pct', 'Error Rate (%)'),\n", + "]\n", + "\n", + "df_enc_s = df_all[df_all['label'] == 'Encrypted'].set_index(DIMS)\n", + "df_plain_s = df_all[df_all['label'] == 'Non-Encrypted'].set_index(DIMS)\n", + "\n", + "rows = []\n", + "for col, label in ALL_METRICS:\n", + " if col not in df_enc_s.columns:\n", + " continue\n", + " for idx in df_enc_s.index:\n", + " if idx not in df_plain_s.index:\n", + " continue\n", + " enc_v = df_enc_s.loc[idx, col]\n", + " plain_v = df_plain_s.loc[idx, col]\n", + " if pd.isna(enc_v) and pd.isna(plain_v):\n", + " continue\n", + " delta = enc_v - plain_v if pd.notna(enc_v) and pd.notna(plain_v) else np.nan\n", + " pct_chg = delta / plain_v * 100 if pd.notna(delta) and plain_v != 0 else np.nan\n", + " rows.append({\n", + " 'Metric': label,\n", + " 'Run Type': idx[0],\n", + " 'Output Tokens': idx[1],\n", + " 'Concurrency': idx[2],\n", + " 'Non-Encrypted': plain_v,\n", + " 'Encrypted': enc_v,\n", + " 'Delta': delta,\n", + " '% Change': pct_chg,\n", + " })\n", + "\n", + "df_summary = pd.DataFrame(rows).sort_values(\n", + " ['Metric', 'Run Type', 'Output Tokens', 'Concurrency']\n", + ")\n", + "\n", + "def _pct_color(val):\n", + " if pd.isna(val): return ''\n", + " if val > 100: return 'background-color: #ff6666'\n", + " if val > 50: return 'background-color: #ffaaaa'\n", + " if val > 20: return 'background-color: #ffd8aa'\n", + " if val > 0: return 'background-color: #fffacc'\n", + " if val < -20: return 'background-color: #aaffaa'\n", + " return ''\n", + "\n", + "df_summary.style \\\n", + " .applymap(_pct_color, subset=['% Change']) \\\n", + " .format({\n", + " 'Non-Encrypted': '{:.3f}',\n", + " 'Encrypted': '{:.3f}',\n", + " 'Delta': '{:+.3f}',\n", + " '% Change': '{:+.1f}%',\n", + " }, na_rep='—')" + ] }, { "cell_type": "markdown", @@ -253,11 +26396,912 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "id": "cell-tee-overhead-table", "metadata": {}, - "outputs": [], - "source": "DIMS = ['num_input_tokens', 'num_output_tokens', 'num_concurrent_requests']\n\ndf_tee_oh = df_all[df_all['label'] == 'Encrypted'].copy()\ndf_tee_oh = df_tee_oh.merge(\n df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n columns={'client_ttft_s_p50': 'client_ttft_plain'}\n ),\n on=DIMS,\n)\n\ndf_tee_oh['enc_time_s'] = df_tee_oh['total_encryption_time_ms_mean'] / 1000\ndf_tee_oh['dec_time_s'] = df_tee_oh['total_decryption_time_ms_mean'] / 1000\ndf_tee_oh['network_s'] = df_tee_oh['server_network_latency_ms_mean'] / 1000\ndf_tee_oh['tee_total_s'] = df_tee_oh['enc_time_s'] + df_tee_oh['dec_time_s'] + df_tee_oh['network_s']\ndf_tee_oh['ttft_delta_s'] = df_tee_oh['client_ttft_s_p50'] - df_tee_oh['client_ttft_plain']\ndf_tee_oh['network_pct'] = df_tee_oh['network_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['enc_pct'] = df_tee_oh['enc_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['dec_pct'] = df_tee_oh['dec_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\ndf_tee_oh['tee_total_pct'] = df_tee_oh['tee_total_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n\nDISPLAY = {\n 'num_input_tokens': 'Input Tokens',\n 'num_output_tokens': 'Output Tokens',\n 'num_concurrent_requests': 'Concurrency',\n 'client_ttft_plain': 'Plain TTFT (s)',\n 'client_ttft_s_p50': 'Enc TTFT (s)',\n 'ttft_delta_s': 'Delta (s)',\n 'enc_time_s': 'Encryption (s)',\n 'dec_time_s': 'Decryption (s)',\n 'network_s': 'Network Hop (s)',\n 'tee_total_s': 'TEE Total (s)',\n 'tee_total_pct': 'TEE % of Enc TTFT',\n 'network_pct': 'Network %',\n 'enc_pct': 'Encrypt %',\n 'dec_pct': 'Decrypt %',\n}\n\ndf_tee_display = (\n df_tee_oh[list(DISPLAY.keys())]\n .rename(columns=DISPLAY)\n .sort_values(['Input Tokens', 'Concurrency'])\n)\n\npct_cols = [c for c in df_tee_display.columns if '%' in c]\ns_cols = [c for c in df_tee_display.columns if '(s)' in c]\n\ndf_tee_display.style \\\n .background_gradient(subset=['TEE % of Enc TTFT'], cmap='YlOrRd') \\\n .format({c: '{:.1f}%' for c in pct_cols}) \\\n .format({c: '{:.4f}' for c in s_cols}, na_rep='—')" + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
 Run TypeOutput TokensConcurrencyPlain TTFT (s)Enc TTFT (s)Delta (s)Encryption (s)Decryption (s)Network Hop (s)TEE Total (s)TEE % of Enc TTFTNetwork %Encrypt %Decrypt %
0Multi Run (10x)10010.25430.37950.12520.01220.00180.33080.344990.87602187.1711203.2208170.484084
1Multi Run (10x)10010.35310.37950.02640.01220.00180.33080.344990.87602187.1711203.2208170.484084
2Multi Run (10x)10010.79550.3795-0.41600.01220.00180.33080.344990.87602187.1711203.2208170.484084
3Multi Run (10x)10010.25430.59050.33620.01760.00030.42680.444775.30509772.2752752.9792210.050601
4Multi Run (10x)10010.35310.59050.23740.01760.00030.42680.444775.30509772.2752752.9792210.050601
5Multi Run (10x)10010.79550.5905-0.20500.01760.00030.42680.444775.30509772.2752752.9792210.050601
6Multi Run (10x)10010.25431.08890.83460.03780.00030.91380.951987.41462083.9165213.4675080.030591
7Multi Run (10x)10010.35311.08890.73580.03780.00030.91380.951987.41462083.9165213.4675080.030591
8Multi Run (10x)10010.79551.08890.29340.03780.00030.91380.951987.41462083.9165213.4675080.030591
9Multi Run (10x)10030.43060.45840.02780.00930.00070.56650.5765125.753076123.5760252.0294720.147579
10Multi Run (10x)10030.85180.4584-0.39340.00930.00070.56650.5765125.753076123.5760252.0294720.147579
11Multi Run (10x)10032.27430.4584-1.81590.00930.00070.56650.5765125.753076123.5760252.0294720.147579
12Multi Run (10x)10030.43060.84790.41730.01760.00040.80060.818696.54304894.4250742.0713650.046609
13Multi Run (10x)10030.85180.8479-0.00390.01760.00040.80060.818696.54304894.4250742.0713650.046609
14Multi Run (10x)10032.27430.8479-1.42640.01760.00040.80060.818696.54304894.4250742.0713650.046609
15Multi Run (10x)10030.43062.15521.72460.03860.00032.02132.060295.59031693.7860991.7896900.014528
16Multi Run (10x)10030.85182.15521.30340.03860.00032.02132.060295.59031693.7860991.7896900.014528
17Multi Run (10x)10032.27432.1552-0.11910.03860.00032.02132.060295.59031693.7860991.7896900.014528
18Multi Run (10x)10050.67900.72460.04560.00890.00050.59840.607883.87394482.5790371.2217640.073144
19Multi Run (10x)10051.23670.7246-0.51210.00890.00050.59840.607883.87394482.5790371.2217640.073144
20Multi Run (10x)10052.29080.7246-1.56620.00890.00050.59840.607883.87394482.5790371.2217640.073144
21Multi Run (10x)10050.67901.70751.02850.01760.00041.07391.092063.95233462.8958891.0323280.024117
22Multi Run (10x)10051.23671.70750.47080.01760.00041.07391.092063.95233462.8958891.0323280.024117
23Multi Run (10x)10052.29081.7075-0.58330.01760.00041.07391.092063.95233462.8958891.0323280.024117
24Multi Run (10x)10050.67901.84381.16480.03390.00041.47411.508481.80694279.9465671.8362300.024146
25Multi Run (10x)10051.23671.84380.60710.03390.00041.47411.508481.80694279.9465671.8362300.024146
26Multi Run (10x)10052.29081.8438-0.44700.03390.00041.47411.508481.80694279.9465671.8362300.024146
27Multi Run (10x)10080.98520.8845-0.10070.00900.00050.65280.662474.88416173.8072701.0215720.055319
28Multi Run (10x)10082.01560.8845-1.13110.00900.00050.65280.662474.88416173.8072701.0215720.055319
29Multi Run (10x)10082.13900.8845-1.25450.00900.00050.65280.662474.88416173.8072701.0215720.055319
30Multi Run (10x)10080.98522.55491.56970.01740.00051.57921.597162.51094861.8095820.6819800.019386
31Multi Run (10x)10082.01562.55490.53930.01740.00051.57921.597162.51094861.8095820.6819800.019386
32Multi Run (10x)10082.13902.55490.41590.01740.00051.57921.597162.51094861.8095820.6819800.019386
33Multi Run (10x)10080.98522.15211.16690.03500.00061.73301.768682.17859880.5280281.6243620.026207
34Multi Run (10x)10082.01562.15210.13650.03500.00061.73301.768682.17859880.5280281.6243620.026207
35Multi Run (10x)10082.13902.15210.01310.03500.00061.73301.768682.17859880.5280281.6243620.026207
36Multi Run (10x)100161.77981.3604-0.41940.00920.00050.85110.860863.27253062.5611950.6738020.037533
37Multi Run (10x)100163.80351.3604-2.44310.00920.00050.85110.860863.27253062.5611950.6738020.037533
38Multi Run (10x)100161.77982.90381.12400.01790.00032.40072.418983.30130282.6737240.6159140.011664
39Multi Run (10x)100163.80352.9038-0.89970.01790.00032.40072.418983.30130282.6737240.6159140.011664
40Multi Run (10x)100322.89901.9853-0.91370.00890.00041.07621.085554.67576254.2061550.4490760.020531
41Multi Run (10x)100326.73811.9853-4.75280.00890.00041.07621.085554.67576254.2061550.4490760.020531
42Multi Run (10x)100322.89904.62901.73000.01880.00043.38923.408373.62933973.2156470.4061110.007580
43Multi Run (10x)100326.73814.6290-2.10910.01880.00043.38923.408373.62933973.2156470.4061110.007580
\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "DIMS = ['run_type', 'num_output_tokens', 'num_concurrent_requests']\n", + "\n", + "df_tee_oh = df_all[df_all['label'] == 'Encrypted'].copy()\n", + "df_tee_oh = df_tee_oh.merge(\n", + " df_all[df_all['label'] == 'Non-Encrypted'][DIMS + ['client_ttft_s_p50']].rename(\n", + " columns={'client_ttft_s_p50': 'client_ttft_plain'}\n", + " ),\n", + " on=DIMS,\n", + ")\n", + "\n", + "df_tee_oh['enc_time_s'] = df_tee_oh['total_encryption_time_ms_mean'] / 1000\n", + "df_tee_oh['dec_time_s'] = df_tee_oh['total_decryption_time_ms_mean'] / 1000\n", + "df_tee_oh['network_s'] = df_tee_oh['server_network_latency_ms_mean'] / 1000\n", + "df_tee_oh['tee_total_s'] = df_tee_oh['enc_time_s'] + df_tee_oh['dec_time_s'] + df_tee_oh['network_s']\n", + "df_tee_oh['ttft_delta_s'] = df_tee_oh['client_ttft_s_p50'] - df_tee_oh['client_ttft_plain']\n", + "df_tee_oh['network_pct'] = df_tee_oh['network_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['enc_pct'] = df_tee_oh['enc_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['dec_pct'] = df_tee_oh['dec_time_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "df_tee_oh['tee_total_pct'] = df_tee_oh['tee_total_s'] / df_tee_oh['client_ttft_s_p50'] * 100\n", + "\n", + "DISPLAY = {\n", + " 'run_type': 'Run Type',\n", + " 'num_output_tokens': 'Output Tokens',\n", + " 'num_concurrent_requests': 'Concurrency',\n", + " 'client_ttft_plain': 'Plain TTFT (s)',\n", + " 'client_ttft_s_p50': 'Enc TTFT (s)',\n", + " 'ttft_delta_s': 'Delta (s)',\n", + " 'enc_time_s': 'Encryption (s)',\n", + " 'dec_time_s': 'Decryption (s)',\n", + " 'network_s': 'Network Hop (s)',\n", + " 'tee_total_s': 'TEE Total (s)',\n", + " 'tee_total_pct': 'TEE % of Enc TTFT',\n", + " 'network_pct': 'Network %',\n", + " 'enc_pct': 'Encrypt %',\n", + " 'dec_pct': 'Decrypt %',\n", + "}\n", + "\n", + "df_tee_display = (\n", + " df_tee_oh[list(DISPLAY.keys())]\n", + " .rename(columns=DISPLAY)\n", + " .sort_values(['Run Type', 'Output Tokens', 'Concurrency'])\n", + ")\n", + "\n", + "pct_cols = [c for c in df_tee_display.columns if '%' in c]\n", + "s_cols = [c for c in df_tee_display.columns if '(s)' in c]\n", + "\n", + "df_tee_display.style \\\n", + " .background_gradient(subset=['TEE % of Enc TTFT'], cmap='YlOrRd') \\\n", + " .format({c: '{:.1f}%' for c in pct_cols}) \\\n", + " .format({c: '{:.4f}' for c in s_cols}, na_rep='—')" + ] }, { "cell_type": "code", @@ -282,6 +27326,14 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4c4e3c11", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -305,4 +27357,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +}