CoolFace
Apppublic

delightfulrachel/GPUandAPIcostestimator

sourceHugging Facemitupdated 1y agoView on Hugging Face
1likes
app.py305 linesDownload Raw Back to root
1import gradio as gr2import pandas as pd3import numpy as np4import plotly.express as px5import plotly.graph_objects as go6 7# Updated pricing data - restructured for better comparison8aws_instances = {9    # T4 GPU Instances (entry level)10    "g4dn.xlarge": {"vcpus": 4, "memory": 16, "gpu": "1x NVIDIA T4", "hourly_rate": 0.526, "gpu_memory": "16GB", "tier": "Entry"},11    "g4dn.2xlarge": {"vcpus": 8, "memory": 32, "gpu": "1x NVIDIA T4", "hourly_rate": 0.752, "gpu_memory": "16GB", "tier": "Entry"},12    13    # A10G GPU Instances (mid-tier)14    "g5.xlarge": {"vcpus": 4, "memory": 16, "gpu": "1x NVIDIA A10G", "hourly_rate": 0.65, "gpu_memory": "24GB", "tier": "Mid"},15    "g5.2xlarge": {"vcpus": 8, "memory": 32, "gpu": "1x NVIDIA A10G", "hourly_rate": 1.006, "gpu_memory": "24GB", "tier": "Mid"},16    17    # V100 GPU Instances (high-tier)18    "p3.2xlarge": {"vcpus": 8, "memory": 61, "gpu": "1x NVIDIA V100", "hourly_rate": 3.06, "gpu_memory": "16GB", "tier": "High"},19    20    21    # Added comparable instances to match GCP22    "p4d.xlarge": {"vcpus": 12, "memory": 85, "gpu": "1x NVIDIA A100", "hourly_rate": 4.10, "gpu_memory": "40GB", "tier": "Premium"},23    "p4d.2xlarge": {"vcpus": 24, "memory": 170, "gpu": "2x NVIDIA A100", "hourly_rate": 8.20, "gpu_memory": "2x40GB", "tier": "Premium"},24    "p4d.4xlarge": {"vcpus": 48, "memory": 340, "gpu": "4x NVIDIA A100", "hourly_rate": 16.40, "gpu_memory": "4x40GB", "tier": "Premium"},25}26 27gcp_instances = {28    # T4 GPU Instances (entry level)29    "n1-standard-4-t4": {"vcpus": 4, "memory": 15, "gpu": "1x NVIDIA T4", "hourly_rate": 0.49, "gpu_memory": "16GB", "tier": "Entry"},30    "n1-standard-8-t4": {"vcpus": 8, "memory": 30, "gpu": "1x NVIDIA T4", "hourly_rate": 0.69, "gpu_memory": "16GB", "tier": "Entry"},31    32    # L4 GPU Instances (mid-tier)33    "g2-standard-4": {"vcpus": 4, "memory": 16, "gpu": "1x NVIDIA L4", "hourly_rate": 0.59, "gpu_memory": "24GB", "tier": "Mid"},34    "g2-standard-8": {"vcpus": 8, "memory": 32, "gpu": "1x NVIDIA L4", "hourly_rate": 0.89, "gpu_memory": "24GB", "tier": "Mid"},35    36    # Added comparable V100 instance37    "n1-standard-8-v100": {"vcpus": 8, "memory": 60, "gpu": "1x NVIDIA V100", "hourly_rate": 2.95, "gpu_memory": "16GB", "tier": "High"},38    39    # A100 GPU Instances (premium)40    "a2-highgpu-1g": {"vcpus": 12, "memory": 85, "gpu": "1x NVIDIA A100", "hourly_rate": 1.46, "gpu_memory": "40GB", "tier": "Premium"},41    "a2-highgpu-2g": {"vcpus": 24, "memory": 170, "gpu": "2x NVIDIA A100", "hourly_rate": 2.93, "gpu_memory": "2x40GB", "tier": "Premium"},42    "a2-highgpu-4g": {"vcpus": 48, "memory": 340, "gpu": "4x NVIDIA A100", "hourly_rate": 5.86, "gpu_memory": "4x40GB", "tier": "Premium"},43}44 45api_pricing = {46    "OpenAI": {47        "GPT-3.5-Turbo": {"input_per_1M": 0.5, "output_per_1M": 1.5, "token_context": 16385},48        "GPT-4o": {"input_per_1M": 5.0, "output_per_1M": 15.0, "token_context": 32768},49        "GPT-4o-mini": {"input_per_1M": 2.5, "output_per_1M": 7.5, "token_context": 32768},50    },51    "TogetherAI": {52        "Llama-3-8B": {"input_per_1M": 0.15, "output_per_1M": 0.15, "token_context": 8192},53        "Llama-3-70B": {"input_per_1M": 0.9, "output_per_1M": 0.9, "token_context": 8192},54        "Llama-2-13B": {"input_per_1M": 0.6, "output_per_1M": 0.6, "token_context": 4096},55        "Llama-2-70B": {"input_per_1M": 2.5, "output_per_1M": 2.5, "token_context": 4096},56        "DeepSeek-Coder-33B": {"input_per_1M": 2.0, "output_per_1M": 2.0, "token_context": 16384},57    },58    "Anthropic": {59        "Claude-3-Opus": {"input_per_1M": 15.0, "output_per_1M": 75.0, "token_context": 200000},60        "Claude-3-Sonnet": {"input_per_1M": 3.0, "output_per_1M": 15.0, "token_context": 200000},61        "Claude-3-Haiku": {"input_per_1M": 0.25, "output_per_1M": 1.25, "token_context": 200000},62    }63}64 65model_sizes = {66    "Small (7B parameters)": {"memory_required": 14},67    "Medium (13B parameters)": {"memory_required": 26},68    "Large (70B parameters)": {"memory_required": 140},69    "XL (180B parameters)": {"memory_required": 360},70}71 72def calculate_aws_cost(instance, hours, storage, reserved=False, spot=False, years=1):73    data = aws_instances[instance]74    rate = data['hourly_rate']75    if spot:76        rate *= 0.377    elif reserved:78        factors = {1: 0.6, 3: 0.4}79        rate *= factors.get(years, 0.6)80    compute = rate * hours81    storage_cost = storage * 0.1082    return {'total_cost': compute + storage_cost, 'details': data}83 84def calculate_gcp_cost(instance, hours, storage, reserved=False, spot=False, years=1):85    data = gcp_instances[instance]86    rate = data['hourly_rate']87    if spot:88        rate *= 0.289    elif reserved:90        factors = {1: 0.7, 3: 0.5}91        rate *= factors.get(years, 0.7)92    compute = rate * hours93    storage_cost = storage * 0.0494    return {'total_cost': compute + storage_cost, 'details': data}95 96def calculate_api_cost(provider, model, in_tokens, out_tokens, calls):97    m = api_pricing[provider][model]98    input_cost = in_tokens * m['input_per_1M'] / 100000099    output_cost = out_tokens * m['output_per_1M'] / 1000000100    call_cost = calls * 0.0001 if provider == 'TogetherAI' else 0101    return {'total_cost': input_cost + output_cost + call_cost, 'details': m}102 103def filter_compatible(instances, min_mem):104    res = {}105    for name, data in instances.items():106        mem_str = data['gpu_memory']107        if 'x' in mem_str and not mem_str.startswith(('1x','2x','4x','8x')):108            val = int(mem_str.replace('GB',''))109        elif 'x' in mem_str:110            parts = mem_str.split('x')111            val = int(parts[0]) * int(parts[1].replace('GB',''))112        else:113            val = int(mem_str.replace('GB',''))114        if val >= min_mem:115            res[name] = data116    return res117 118def generate_cost_comparison(119    compute_hours, tokens_per_month, input_ratio, api_calls,120    model_size, storage_gb, reserved_instances, spot_instances, multi_year_commitment,121    comparison_tier122):123    years = int(multi_year_commitment)124    in_tokens = tokens_per_month * 1000000 * (input_ratio/100)125    out_tokens = tokens_per_month * 1000000 - in_tokens126    min_mem = model_sizes[model_size]['memory_required']127 128    # Filter by both memory requirements and tier if a tier is selected129    aws_comp = filter_compatible(aws_instances, min_mem)130    gcp_comp = filter_compatible(gcp_instances, min_mem)131    132    if comparison_tier != "All":133        aws_comp = {k: v for k, v in aws_comp.items() if v.get('tier', '') == comparison_tier}134        gcp_comp = {k: v for k, v in gcp_comp.items() if v.get('tier', '') == comparison_tier}135 136    results = []137 138    # AWS table139    aws_html = '<h3>AWS Instances</h3>'140    aws_html += '<table width="100%"><tr><th>Instance</th><th>vCPUs</th><th>Memory</th><th>GPU</th><th>Tier</th><th>Monthly Cost ($)</th></tr>'141    if aws_comp:142        for inst in aws_comp:143            res = calculate_aws_cost(inst, compute_hours, storage_gb, reserved_instances, spot_instances, years)144            aws_html += f'<tr><td>{inst}</td><td>{res["details"]["vcpus"]}</td><td>{res["details"]["memory"]}GB</td><td>{res["details"]["gpu"]}</td><td>{res["details"].get("tier", "")}</td><td>${res["total_cost"]:.2f}</td></tr>'145        # best AWS146        best_aws = min(aws_comp, key=lambda x: calculate_aws_cost(x, compute_hours, storage_gb, reserved_instances, spot_instances, years)['total_cost'])147        best_aws_cost = calculate_aws_cost(best_aws, compute_hours, storage_gb, reserved_instances, spot_instances, years)['total_cost']148        best_aws_tier = aws_instances[best_aws].get('tier', '')149        results.append({'provider': f'AWS ({best_aws})', 'cost': best_aws_cost, 'type': 'Cloud', 'tier': best_aws_tier})150    else:151        aws_html += '<tr><td colspan="6">No compatible instances</td></tr>'152    aws_html += '</table>'153 154    # GCP table155    gcp_html = '<h3>GCP Instances</h3>'156    gcp_html += '<table width="100%"><tr><th>Instance</th><th>vCPUs</th><th>Memory</th><th>GPU</th><th>Tier</th><th>Monthly Cost ($)</th></tr>'157    if gcp_comp:158        for inst in gcp_comp:159            res = calculate_gcp_cost(inst, compute_hours, storage_gb, reserved_instances, spot_instances, years)160            gcp_html += f'<tr><td>{inst}</td><td>{res["details"]["vcpus"]}</td><td>{res["details"]["memory"]}GB</td><td>{res["details"]["gpu"]}</td><td>{res["details"].get("tier", "")}</td><td>${res["total_cost"]:.2f}</td></tr>'161        best_gcp = min(gcp_comp, key=lambda x: calculate_gcp_cost(x, compute_hours, storage_gb, reserved_instances, spot_instances, years)['total_cost'])162        best_gcp_cost = calculate_gcp_cost(best_gcp, compute_hours, storage_gb, reserved_instances, spot_instances, years)['total_cost']163        best_gcp_tier = gcp_instances[best_gcp].get('tier', '')164        results.append({'provider': f'GCP ({best_gcp})', 'cost': best_gcp_cost, 'type': 'Cloud', 'tier': best_gcp_tier})165    else:166        gcp_html += '<tr><td colspan="6">No compatible instances</td></tr>'167    gcp_html += '</table>'168 169    # API table170    api_html = '<h3>API Options</h3>'171    api_html += '<table width="100%"><tr><th>Provider</th><th>Model</th><th>Input Cost</th><th>Output Cost</th><th>Total Cost ($)</th><th>Context</th></tr>'172    api_costs = {}173    for prov in api_pricing:174        for mdl in api_pricing[prov]:175            res = calculate_api_cost(prov, mdl, in_tokens, out_tokens, api_calls)176            details = api_pricing[prov][mdl]177            api_html += f'<tr><td>{prov}</td><td>{mdl}</td><td>${in_tokens * details["input_per_1M"] / 1000000:.2f}</td><td>${out_tokens * details["output_per_1M"] / 1000000:.2f}</td><td>${res["total_cost"]:.2f}</td><td>{details["token_context"]:,}</td></tr>'178            api_costs[(prov, mdl)] = res['total_cost']179    api_html += '</table>'180    181    if api_costs:182        best_api = min(api_costs, key=api_costs.get)183        results.append({'provider': f'{best_api[0]} ({best_api[1]})', 'cost': api_costs[best_api], 'type': 'API', 'tier': 'API'})184 185    # Direct comparison tables for similar instances186    direct_comparison_html = ""187    if comparison_tier != "All" and comparison_tier != "API":188        direct_comparison_html = f'<h3>Direct {comparison_tier} Tier Comparison</h3>'189        direct_comparison_html += '<table width="100%"><tr><th>Provider</th><th>Instance</th><th>vCPUs</th><th>Memory</th><th>GPU</th><th>Monthly Cost ($)</th></tr>'190        191        aws_filtered = {k: v for k, v in aws_instances.items() if v.get('tier', '') == comparison_tier}192        gcp_filtered = {k: v for k, v in gcp_instances.items() if v.get('tier', '') == comparison_tier}193        194        # Group by vCPU for comparison195        vcpu_groups = {}196        for inst, data in aws_filtered.items():197            vcpu = data['vcpus']198            if vcpu not in vcpu_groups:199                vcpu_groups[vcpu] = {'aws': [], 'gcp': []}200            vcpu_groups[vcpu]['aws'].append(inst)201        202        for inst, data in gcp_filtered.items():203            vcpu = data['vcpus']204            if vcpu not in vcpu_groups:205                vcpu_groups[vcpu] = {'aws': [], 'gcp': []}206            vcpu_groups[vcpu]['gcp'].append(inst)207        208        # Display direct comparisons209        for vcpu in sorted(vcpu_groups.keys()):210            group = vcpu_groups[vcpu]211            for aws_inst in group['aws']:212                aws_cost = calculate_aws_cost(aws_inst, compute_hours, storage_gb, reserved_instances, spot_instances, years)213                aws_data = aws_cost['details']214                direct_comparison_html += f'<tr><td>AWS</td><td>{aws_inst}</td><td>{aws_data["vcpus"]}</td><td>{aws_data["memory"]}GB</td><td>{aws_data["gpu"]}</td><td>${aws_cost["total_cost"]:.2f}</td></tr>'215            216            for gcp_inst in group['gcp']:217                gcp_cost = calculate_gcp_cost(gcp_inst, compute_hours, storage_gb, reserved_instances, spot_instances, years)218                gcp_data = gcp_cost['details']219                direct_comparison_html += f'<tr><td>GCP</td><td>{gcp_inst}</td><td>{gcp_data["vcpus"]}</td><td>{gcp_data["memory"]}GB</td><td>{gcp_data["gpu"]}</td><td>${gcp_cost["total_cost"]:.2f}</td></tr>'220            221            # Add separator between different vCPU groups222            if vcpu != sorted(vcpu_groups.keys())[-1]:223                direct_comparison_html += '<tr><td colspan="6" style="border-bottom: 1px solid #ccc; height: 10px;"></td></tr>'224        225        direct_comparison_html += '</table>'226 227    # Chart with annotations228    df = pd.DataFrame(results)229    colors = {'Entry': '#66BB6A', 'Mid': '#42A5F5', 'High': '#FFA726', 'Premium': '#EF5350', 'API': '#AB47BC'}230    231    # Create figure using plotly graph objects for more control232    fig = go.Figure()233    234    # Add bars235    for i, row in df.iterrows():236        tier_color = colors.get(row.get('tier', 'API'), '#9E9E9E')237        fig.add_trace(go.Bar(238            x=[row['provider']], 239            y=[row['cost']], 240            name=row['provider'],241            marker_color=tier_color242        ))243    244    # Add annotations on top of each bar245    for i, row in df.iterrows():246        fig.add_annotation(247            x=row['provider'],248            y=row['cost'],249            text=f"${row['cost']:.2f}",250            showarrow=False,251            yshift=10,  # Position above the bar252            font=dict(size=14)253        )254    255    # Update layout256    fig.update_layout(257        showlegend=False,258        height=500,259        yaxis=dict(title='Monthly Cost ($)', tickprefix='$'),260        xaxis=dict(title=''),261        title='Cost Comparison'262    )263 264    html = f"""265    <div style='padding:20px;font-family:Arial;'>266      {direct_comparison_html}267      {aws_html}268      {gcp_html}269      {api_html}270    </div>271    """272    return html, fig273 274# UI setup275with gr.Blocks(title="Cloud Cost Estimator", theme=gr.themes.Soft(primary_hue="indigo")) as demo:276    gr.HTML('<h1 style="text-align:center;">Cloud Cost Estimator</h1>')277    with gr.Row():278        with gr.Column(scale=1):279            compute_hours = gr.Slider(label="Compute Hours per Month", minimum=1, maximum=300, value=50)280            tokens_per_month = gr.Slider(label="Tokens per Month (M)", minimum=1, maximum=200, value=5)281            input_ratio = gr.Slider(label="Input Ratio (%)", minimum=10, maximum=70, value=25)282            api_calls = gr.Slider(label="API Calls per Month", minimum=100, maximum=100000, value=5000, step=100)283            model_size = gr.Dropdown(label="Model Size", choices=list(model_sizes.keys()), value="Medium (13B parameters)")284            storage_gb = gr.Slider(label="Storage (GB)", minimum=10, maximum=1000, value=100)285            comparison_tier = gr.Radio(label="Comparison Tier", choices=["All", "Entry", "Mid", "High", "Premium", "API"], value="All")286            reserved_instances = gr.Checkbox(label="Reserved Instances", value=False)287            spot_instances = gr.Checkbox(label="Spot Instances", value=False)288            multi_year_commitment = gr.Radio(label="Commitment Period (years)", choices=["1","3"], value="1")289        with gr.Column(scale=2):290            out_html = gr.HTML()291            out_plot = gr.Plot()292    293    # Create inputs list for the function294    inputs = [compute_hours, tokens_per_month, input_ratio, api_calls,295             model_size, storage_gb, reserved_instances, spot_instances, multi_year_commitment, comparison_tier]296    outputs = [out_html, out_plot]297    298    # Initial calculation on load299    demo.load(generate_cost_comparison, inputs, outputs)300    301    # Update on each input change302    for input_component in inputs:303        input_component.change(generate_cost_comparison, inputs, outputs)304 305demo.launch()