bgloh/functiongemma-tutorial
0
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>FUNCTIONGEMMA | TUTORIAL</title>7 <link rel="preconnect" href="https://fonts.googleapis.com">8 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>9 <link href="https://fonts.googleapis.com/css2?family=Bungee&family=JetBrains+Mono:wght@400;700;800&family=Space+Grotesk:wght@400;700&display=swap" rel="stylesheet">10 11 <!-- Google Analytics -->12 <script async src="https://www.googletagmanager.com/gtag/js?id=G-2Q4M55VKPR"></script>13 <script>14 window.dataLayer = window.dataLayer || [];15 function gtag(){dataLayer.push(arguments);}16 gtag('js', new Date());17 gtag('config', 'G-2Q4M55VKPR', {18 page_path: window.location.pathname,19 anonymize_ip: true20 });21 </script>22 <style>23 :root {24 --black: #000000;25 --white: #FFFFFF;26 --yellow: #FFFF00;27 --red: #FF0000;28 --green: #00FF00;29 --cyan: #00FFFF;30 --border-width: 4px;31 --shadow-offset: 8px;32 }33 34 * {35 margin: 0;36 padding: 0;37 box-sizing: border-box;38 }39 40 body {41 font-family: 'Space Grotesk', sans-serif;42 background: var(--black);43 color: var(--white);44 min-height: 100vh;45 padding: 20px;46 line-height: 1.6;47 position: relative;48 overflow-x: hidden;49 }50 51 body::before {52 content: '';53 position: fixed;54 top: 0;55 left: 0;56 width: 100%;57 height: 100%;58 background: 59 repeating-linear-gradient(90deg, transparent, transparent 50px, rgba(255,255,0,0.03) 50px, rgba(255,255,0,0.03) 52px),60 repeating-linear-gradient(0deg, transparent, transparent 50px, rgba(255,0,0,0.03) 50px, rgba(255,0,0,0.03) 52px);61 pointer-events: none;62 z-index: 0;63 }64 65 .container {66 max-width: 1600px;67 margin: 0 auto;68 position: relative;69 z-index: 1;70 }71 72 .header {73 background: var(--black);74 border: var(--border-width) solid var(--white);75 padding: 40px;76 margin-bottom: 30px;77 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--yellow);78 position: relative;79 animation: slideDown 0.6s ease-out;80 }81 82 @keyframes slideDown {83 from {84 opacity: 0;85 transform: translateY(-30px);86 }87 to {88 opacity: 1;89 transform: translateY(0);90 }91 }92 93 .header::before {94 content: '';95 position: absolute;96 top: -4px;97 left: -4px;98 right: -4px;99 bottom: -4px;100 border: 2px solid var(--yellow);101 z-index: -1;102 }103 104 .header h1 {105 font-family: 'Bungee', cursive;106 font-size: 3.5em;107 color: var(--yellow);108 margin-bottom: 15px;109 text-transform: uppercase;110 letter-spacing: 2px;111 text-shadow: 4px 4px 0 var(--red);112 line-height: 1.1;113 }114 115 .header p {116 font-size: 1.3em;117 color: var(--white);118 font-weight: 700;119 text-transform: uppercase;120 letter-spacing: 1px;121 }122 123 .model-loading-overlay {124 position: fixed;125 top: 0;126 left: 0;127 width: 100%;128 height: 100%;129 background: var(--black);130 z-index: 10000;131 display: flex;132 flex-direction: column;133 align-items: center;134 justify-content: center;135 border: var(--border-width) solid var(--yellow);136 }137 138 .model-loading-overlay.hidden {139 display: none;140 }141 142 .loading-content {143 max-width: 800px;144 padding: 40px;145 background: var(--black);146 border: var(--border-width) solid var(--white);147 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--cyan);148 }149 150 .loading-title {151 font-family: 'Bungee', cursive;152 font-size: 2.5em;153 color: var(--yellow);154 margin-bottom: 30px;155 text-transform: uppercase;156 text-align: center;157 animation: pulse 2s ease-in-out infinite;158 }159 160 @keyframes pulse {161 0%, 100% { opacity: 1; }162 50% { opacity: 0.7; }163 }164 165 .loading-steps {166 list-style: none;167 margin: 20px 0;168 }169 170 .loading-step {171 padding: 15px;172 margin: 10px 0;173 background: var(--black);174 border: 2px solid var(--white);175 color: var(--white);176 font-family: 'JetBrains Mono', monospace;177 position: relative;178 transition: all 0.3s ease;179 }180 181 .loading-step.active {182 border-color: var(--yellow);183 background: rgba(255, 255, 0, 0.1);184 box-shadow: 4px 4px 0 var(--yellow);185 }186 187 .loading-step.completed {188 border-color: var(--green);189 background: rgba(0, 255, 0, 0.1);190 }191 192 .loading-step.completed::after {193 content: ' ✓';194 color: var(--green);195 font-weight: bold;196 }197 198 .model-info-grid {199 display: grid;200 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));201 gap: 20px;202 margin: 30px 0;203 }204 205 .info-card {206 background: var(--black);207 border: var(--border-width) solid var(--white);208 padding: 20px;209 box-shadow: 6px 6px 0 var(--cyan);210 }211 212 .info-card h3 {213 font-family: 'Bungee', cursive;214 color: var(--cyan);215 font-size: 1.2em;216 margin-bottom: 10px;217 text-transform: uppercase;218 }219 220 .info-card p {221 font-family: 'JetBrains Mono', monospace;222 color: var(--white);223 font-size: 0.9em;224 }225 226 .resource-links {227 margin: 30px 0;228 padding: 20px;229 background: var(--black);230 border: var(--border-width) solid var(--yellow);231 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--red);232 }233 234 .resource-links h3 {235 font-family: 'Bungee', cursive;236 color: var(--yellow);237 margin-bottom: 15px;238 text-transform: uppercase;239 font-size: 1.5em;240 }241 242 .resource-links ul {243 list-style: none;244 display: grid;245 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));246 gap: 15px;247 }248 249 .resource-links li {250 padding: 15px;251 background: var(--black);252 border: 2px solid var(--white);253 }254 255 .resource-links a {256 color: var(--cyan);257 text-decoration: none;258 font-family: 'JetBrains Mono', monospace;259 font-weight: 700;260 transition: all 0.2s ease;261 display: block;262 }263 264 .resource-links a:hover {265 color: var(--yellow);266 transform: translateX(5px);267 }268 269 .progress-bar {270 background: var(--black);271 border: var(--border-width) solid var(--white);272 padding: 20px;273 margin-bottom: 30px;274 display: flex;275 align-items: center;276 gap: 20px;277 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--cyan);278 }279 280 .progress-fill {281 flex: 1;282 height: 40px;283 background: var(--black);284 border: 2px solid var(--white);285 position: relative;286 overflow: hidden;287 }288 289 .progress-inner {290 height: 100%;291 background: var(--yellow);292 transition: width 0.5s ease;293 display: flex;294 align-items: center;295 justify-content: center;296 color: var(--black);297 font-weight: 800;298 font-family: 'Bungee', cursive;299 font-size: 1.1em;300 text-transform: uppercase;301 }302 303 .main-content {304 display: grid;305 grid-template-columns: 320px 1fr;306 gap: 30px;307 }308 309 .sidebar {310 background: var(--black);311 border: var(--border-width) solid var(--white);312 padding: 25px;313 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--red);314 height: fit-content;315 position: sticky;316 top: 20px;317 }318 319 .model-status {320 background: var(--black);321 border: 2px solid var(--white);322 padding: 15px;323 margin-bottom: 25px;324 text-align: center;325 font-family: 'JetBrains Mono', monospace;326 font-weight: 700;327 }328 329 .model-status.loaded {330 border-color: var(--green);331 box-shadow: 4px 4px 0 var(--green);332 }333 334 .model-status-text {335 color: var(--white);336 }337 338 .model-status.loaded .model-status-text {339 color: var(--green);340 }341 342 .lesson-list {343 list-style: none;344 }345 346 .lesson-item {347 padding: 18px;348 margin: 12px 0;349 background: var(--black);350 border: 2px solid var(--white);351 cursor: pointer;352 transition: all 0.2s ease;353 font-weight: 700;354 text-transform: uppercase;355 font-size: 0.9em;356 letter-spacing: 0.5px;357 }358 359 .lesson-item:hover {360 transform: translate(4px, 4px);361 box-shadow: -4px -4px 0 var(--yellow);362 }363 364 .lesson-item.active {365 background: var(--yellow);366 color: var(--black);367 border-color: var(--yellow);368 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--red);369 }370 371 .lesson-item.completed {372 border-color: var(--green);373 }374 375 .lesson-item.completed::after {376 content: " ✓";377 color: var(--green);378 font-weight: bold;379 }380 381 .content-area {382 background: var(--black);383 border: var(--border-width) solid var(--white);384 padding: 40px;385 box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--cyan);386 min-height: 600px;387 }388 389 .lesson-content {390 display: none;391 }392 393 .lesson-content.active {394 display: block;395 animation: fadeInSlide 0.5s ease;396 }397 398 @keyframes fadeInSlide {399 from {400 opacity: 0;401 transform: translateY(20px);402 }403 to {404 opacity: 1;405 transform: translateY(0);406 }407 }408 409 .lesson-title {410 font-family: 'Bungee', cursive;411 font-size: 2.5em;412 margin-bottom: 25px;413 color: var(--yellow);414 text-transform: uppercase;415 text-shadow: 3px 3px 0 var(--red);416 border-bottom: var(--border-width) solid var(--yellow);417 padding-bottom: 15px;418 }419 420 .lesson-description {421 font-size: 1.1em;422 line-height: 1.8;423 margin-bottom: 30px;424 color: var(--white);425 }426 427 .code-block {428 background: var(--black);429 border: var(--border-width) solid var(--yellow);430 padding: 25px;431 margin: 25px 0;432 overflow-x: auto;433 position: relative;434 box-shadow: 6px 6px 0 var(--cyan);435 }436 437 .code-block pre {438 color: var(--green);439 font-family: 'JetBrains Mono', monospace;440 font-size: 14px;441 line-height: 1.8;442 margin: 0;443 font-weight: 400;444 }445 446 .code-comment {447 color: #888;448 font-style: italic;449 }450 451 .code-keyword {452 color: var(--red);453 font-weight: 700;454 }455 456 .code-string {457 color: var(--cyan);458 }459 460 .code-function {461 color: var(--yellow);462 }463 464 .interactive-demo {465 background: var(--black);466 border: var(--border-width) solid var(--white);467 padding: 25px;468 margin: 25px 0;469 box-shadow: 6px 6px 0 var(--red);470 }471 472 .interactive-demo h3 {473 font-family: 'Bungee', cursive;474 color: var(--yellow);475 margin-bottom: 20px;476 text-transform: uppercase;477 font-size: 1.5em;478 }479 480 .demo-controls {481 display: flex;482 gap: 15px;483 margin-bottom: 20px;484 flex-wrap: wrap;485 }486 487 button {488 background: var(--black);489 color: var(--white);490 border: var(--border-width) solid var(--white);491 padding: 15px 30px;492 font-size: 16px;493 font-weight: 800;494 cursor: pointer;495 transition: all 0.2s ease;496 font-family: 'Space Grotesk', sans-serif;497 text-transform: uppercase;498 letter-spacing: 1px;499 box-shadow: 4px 4px 0 var(--yellow);500 }501 502 button:hover:not(:disabled) {503 transform: translate(2px, 2px);504 box-shadow: 2px 2px 0 var(--yellow);505 }506 507 button:active:not(:disabled) {508 transform: translate(4px, 4px);509 box-shadow: 0 0 0 var(--yellow);510 }511 512 button:disabled {513 background: #333;514 border-color: #666;515 color: #666;516 cursor: not-allowed;517 box-shadow: none;518 }519 520 .btn-success {521 border-color: var(--green);522 box-shadow: 4px 4px 0 var(--green);523 color: var(--green);524 }525 526 .btn-success:hover:not(:disabled) {527 box-shadow: 2px 2px 0 var(--green);528 }529 530 .btn-danger {531 border-color: var(--red);532 box-shadow: 4px 4px 0 var(--red);533 color: var(--red);534 }535 536 .btn-danger:hover:not(:disabled) {537 box-shadow: 2px 2px 0 var(--red);538 }539 540 .output-area {541 background: var(--black);542 border: var(--border-width) solid var(--cyan);543 padding: 20px;544 margin: 20px 0;545 min-height: 150px;546 max-height: 500px;547 overflow-y: auto;548 font-family: 'JetBrains Mono', monospace;549 font-size: 13px;550 box-shadow: 6px 6px 0 var(--yellow);551 }552 553 .token-visualization {554 display: flex;555 flex-wrap: wrap;556 gap: 15px;557 margin: 25px 0;558 }559 560 .token-box {561 background: var(--black);562 border: 2px solid var(--white);563 padding: 15px 20px;564 text-align: center;565 min-width: 140px;566 transition: all 0.2s ease;567 box-shadow: 4px 4px 0 var(--cyan);568 }569 570 .token-box:hover {571 transform: translate(-2px, -2px);572 box-shadow: 6px 6px 0 var(--yellow);573 border-color: var(--yellow);574 }575 576 .token-id {577 font-size: 11px;578 color: #888;579 margin-bottom: 8px;580 font-family: 'JetBrains Mono', monospace;581 }582 583 .token-text {584 font-size: 18px;585 color: var(--green);586 font-weight: 800;587 font-family: 'JetBrains Mono', monospace;588 }589 590 .hint-box, .info-box, .success-box, .error-box {591 background: var(--black);592 border-left: var(--border-width) solid;593 padding: 20px;594 margin: 20px 0;595 box-shadow: 4px 4px 0;596 }597 598 .hint-box {599 border-color: var(--yellow);600 box-shadow: 4px 4px 0 var(--yellow);601 }602 603 .hint-box h4 {604 color: var(--yellow);605 margin-bottom: 12px;606 font-family: 'Bungee', cursive;607 text-transform: uppercase;608 font-size: 1.2em;609 }610 611 .info-box {612 border-color: var(--cyan);613 box-shadow: 4px 4px 0 var(--cyan);614 }615 616 .info-box h4 {617 color: var(--cyan);618 margin-bottom: 12px;619 font-family: 'Bungee', cursive;620 text-transform: uppercase;621 font-size: 1.2em;622 }623 624 .success-box {625 border-color: var(--green);626 box-shadow: 4px 4px 0 var(--green);627 }628 629 .success-box h4 {630 color: var(--green);631 margin-bottom: 12px;632 font-family: 'Bungee', cursive;633 text-transform: uppercase;634 font-size: 1.2em;635 }636 637 .error-box {638 border-color: var(--red);639 box-shadow: 4px 4px 0 var(--red);640 }641 642 .error-box h4 {643 color: var(--red);644 margin-bottom: 12px;645 font-family: 'Bungee', cursive;646 text-transform: uppercase;647 font-size: 1.2em;648 }649 650 .comparison-table {651 width: 100%;652 border-collapse: separate;653 border-spacing: 0;654 margin: 25px 0;655 border: var(--border-width) solid var(--white);656 }657 658 .comparison-table th,659 .comparison-table td {660 padding: 15px;661 text-align: left;662 border-bottom: 2px solid var(--white);663 border-right: 2px solid var(--white);664 }665 666 .comparison-table th {667 background: var(--yellow);668 color: var(--black);669 font-family: 'Bungee', cursive;670 text-transform: uppercase;671 font-weight: 400;672 }673 674 .comparison-table tr:hover {675 background: rgba(255, 255, 0, 0.1);676 }677 678 .comparison-table td:last-child,679 .comparison-table th:last-child {680 border-right: none;681 }682 683 .achievement-badge {684 display: inline-block;685 background: var(--yellow);686 color: var(--black);687 padding: 8px 15px;688 border: 2px solid var(--black);689 font-size: 12px;690 font-weight: 800;691 margin: 5px;692 text-transform: uppercase;693 font-family: 'Bungee', cursive;694 box-shadow: 3px 3px 0 var(--red);695 }696 697 input[type="text"],698 textarea {699 background: var(--black);700 border: var(--border-width) solid var(--white);701 color: var(--white);702 padding: 15px;703 font-size: 14px;704 width: 100%;705 font-family: 'JetBrains Mono', monospace;706 margin-bottom: 15px;707 box-shadow: 4px 4px 0 var(--cyan);708 }709 710 input[type="text"]:focus,711 textarea:focus {712 outline: none;713 border-color: var(--yellow);714 box-shadow: 4px 4px 0 var(--yellow);715 }716 717 .loading-spinner {718 display: inline-block;719 width: 24px;720 height: 24px;721 border: 3px solid var(--white);722 border-top-color: var(--yellow);723 animation: spin 1s linear infinite;724 }725 726 @keyframes spin {727 to { transform: rotate(360deg); }728 }729 730 .playground-grid {731 display: grid;732 grid-template-columns: 1fr 1fr;733 gap: 25px;734 margin: 25px 0;735 }736 737 .playground-section {738 background: var(--black);739 border: var(--border-width) solid var(--white);740 padding: 25px;741 box-shadow: 6px 6px 0 var(--red);742 }743 744 .playground-section h3 {745 font-family: 'Bungee', cursive;746 color: var(--yellow);747 margin-bottom: 15px;748 text-transform: uppercase;749 }750 751 textarea {752 min-height: 300px;753 resize: vertical;754 }755 756 .resource-badge {757 display: inline-block;758 background: var(--black);759 border: 2px solid var(--cyan);760 padding: 5px 10px;761 margin: 5px;762 font-size: 11px;763 font-family: 'JetBrains Mono', monospace;764 color: var(--cyan);765 text-transform: uppercase;766 }767 768 .example-item {769 background: var(--black);770 border: 2px solid var(--white);771 padding: 20px;772 margin: 15px 0;773 box-shadow: 4px 4px 0 var(--cyan);774 position: relative;775 }776 777 .example-item-header {778 display: flex;779 justify-content: space-between;780 align-items: center;781 margin-bottom: 15px;782 }783 784 .example-item h4 {785 font-family: 'Bungee', cursive;786 color: var(--yellow);787 font-size: 1em;788 margin: 0;789 text-transform: uppercase;790 }791 792 .example-item input,793 .example-item textarea {794 width: 100%;795 margin-bottom: 10px;796 font-size: 13px;797 }798 799 .example-item textarea {800 min-height: 60px;801 resize: vertical;802 }803 804 .remove-example-btn {805 background: var(--black);806 color: var(--red);807 border: 2px solid var(--red);808 padding: 8px 15px;809 font-size: 12px;810 cursor: pointer;811 font-weight: 700;812 text-transform: uppercase;813 box-shadow: 3px 3px 0 var(--red);814 }815 816 .remove-example-btn:hover {817 transform: translate(1px, 1px);818 box-shadow: 2px 2px 0 var(--red);819 }820 821 @media (max-width: 1024px) {822 .main-content {823 grid-template-columns: 1fr;824 }825 .sidebar {826 position: static;827 }828 .playground-grid {829 grid-template-columns: 1fr;830 }831 .header h1 {832 font-size: 2.5em;833 }834 }835 836 @media (max-width: 768px) {837 .header h1 {838 font-size: 2em;839 }840 .lesson-title {841 font-size: 1.8em;842 }843 .model-info-grid {844 grid-template-columns: 1fr;845 }846 .resource-links ul {847 grid-template-columns: 1fr;848 }849 }850 </style>851</head>852<body>853 <!-- Model Loading Overlay -->854 <div class="model-loading-overlay" id="loadingOverlay">855 <div class="loading-content">856 <h2 class="loading-title">LOADING FUNCTIONGEMMA</h2>857 <ul class="loading-steps" id="loadingSteps">858 <li class="loading-step" id="step1">Initializing transformers.js...</li>859 <li class="loading-step" id="step2">Loading tokenizer...</li>860 <li class="loading-step" id="step3">Detecting device capabilities...</li>861 <li class="loading-step" id="step4">Loading ONNX model...</li>862 <li class="loading-step" id="step5">Model ready!</li>863 </ul>864 <div class="model-info-grid" id="modelInfoGrid" style="display: none;">865 <div class="info-card">866 <h3>MODEL</h3>867 <p>functiongemma-270m-it-ONNX</p>868 </div>869 <div class="info-card">870 <h3>PARAMETERS</h3>871 <p>270 Million</p>872 </div>873 <div class="info-card">874 <h3>FORMAT</h3>875 <p id="modelFormat">Detecting...</p>876 </div>877 <div class="info-card">878 <h3>DEVICE</h3>879 <p id="modelDevice">Detecting...</p>880 </div>881 </div>882 </div>883 </div>884 885 <div class="container">886 <div class="header">887 <h1>FUNCTIONGEMMA</h1>888 <p>INTERACTIVE TUTORIAL</p>889 <p style="font-size: 0.9em; margin-top: 10px; font-weight: 400; text-transform: none;">Master Function Calling, Tokenization & Prompt Engineering</p>890 </div>891 892 <div class="progress-bar">893 <div class="progress-fill">894 <div class="progress-inner" id="progressBar" style="width: 0%">0% COMPLETE</div>895 </div>896 <div id="achievements"></div>897 </div>898 899 <div class="main-content">900 <div class="sidebar">901 <div class="model-status" id="modelStatus">902 <strong>STATUS:</strong> <span class="model-status-text" id="modelStatusText">READY</span>903 </div>904 <ul class="lesson-list">905 <li class="lesson-item active" data-lesson="0">🚀 WELCOME</li>906 <li class="lesson-item" data-lesson="1">🔤 TOKENIZATION</li>907 <li class="lesson-item" data-lesson="2">❌ ZERO-SHOT</li>908 <li class="lesson-item" data-lesson="3">⚠️ ONE-SHOT</li>909 <li class="lesson-item" data-lesson="4">✅ FEW-SHOT</li>910 <li class="lesson-item" data-lesson="5">🔍 TOKEN DIVE</li>911 <li class="lesson-item" data-lesson="6">🎯 PLAYGROUND</li>912 <li class="lesson-item" data-lesson="7">📚 RESOURCES</li>913 </ul>914 </div>915 916 <div class="content-area">917 <!-- Lesson 0: Welcome -->918 <div class="lesson-content active" data-lesson="0">919 <h2 class="lesson-title">WELCOME TO FUNCTIONGEMMA</h2>920 <div class="lesson-description">921 <p>Welcome to the tutorial on FunctionGemma. This interactive experience will teach you everything about function calling, tokenization, and prompt engineering through hands-on experimentation.</p>922 923 <div class="info-box">924 <h4>WHAT YOU'LL LEARN</h4>925 <ul style="margin-left: 20px; line-height: 2.5;">926 <li>How tokenization works in language models</li>927 <li>Why zero-shot function calling fails</li>928 <li>How few-shot examples solve the problem</li>929 <li>Token-level analysis and debugging</li>930 <li>Best practices for prompt engineering</li>931 <li>ONNX model optimization and deployment</li>932 </ul>933 </div>934 935 <div class="hint-box">936 <h4>ABOUT FUNCTIONGEMMA-270M-IT-ONNX</h4>937 <p><strong>Model:</strong> onnx-community/functiongemma-270m-it-ONNX</p>938 <p><strong>Size:</strong> 270 million parameters</p>939 <p><strong>Purpose:</strong> Specialized for function calling tasks</p>940 <p><strong>Format:</strong> ONNX quantized (q4 for WebGPU, q8 for WASM)</p>941 <p><strong>Key Finding:</strong> Requires few-shot examples to generate correct function calls!</p>942 <p><strong>Architecture:</strong> Based on Google's Gemma 3 270M, fine-tuned for function calling</p>943 </div>944 945 <div class="success-box">946 <h4>MODEL LOADED SUCCESSFULLY</h4>947 <p>The model has been automatically loaded and is ready to use. You can now proceed with the lessons!</p>948 </div>949 </div>950 </div>951 952 <!-- Lesson 1: Tokenization -->953 <div class="lesson-content" data-lesson="1">954 <h2 class="lesson-title">TOKENIZATION BASICS</h2>955 <div class="lesson-description">956 <p>Tokenization is the process of converting text into tokens (numbers) that the model can understand. Let's explore this interactively!</p>957 958 <div class="info-box">959 <h4>WHAT IS TOKENIZATION?</h4>960 <p>Language models don't understand words directly. They work with <strong>tokens</strong> - numeric IDs that represent pieces of text. A token can be a word, part of a word, or even a single character.</p>961 </div>962 963 <div class="interactive-demo">964 <h3>TRY IT YOURSELF</h3>965 <input type="text" id="tokenizeInput" placeholder="Enter text to tokenize..." value="call:get_current_temperature">966 <button onclick="demonstrateTokenization()">TOKENIZE</button>967 <div id="tokenizationOutput" class="output-area" style="margin-top: 15px;"></div>968 </div>969 970 <div class="code-block">971 <pre><span class="code-comment">// How tokenization works in code:</span>972<span class="code-keyword">const</span> text = <span class="code-string">"call:get_current_temperature"</span>;973<span class="code-comment">// Tokenize the text</span>974<span class="code-keyword">const</span> tokens = <span class="code-function">await tokenizer</span>.encode(text);975<span class="code-comment">// Result: [6639, 236787, 828, 236779, 4002, 236779, 27495]</span>976<span class="code-comment">// Each number represents a token ID</span>977 978<span class="code-comment">// Decode tokens back to text</span>979<span class="code-keyword">const</span> decoded = <span class="code-function">await tokenizer</span>.decode(tokens);980<span class="code-comment">// Result: "call:get_current_temperature"</span></pre>981 </div>982 983 <div class="hint-box">984 <h4>KEY INSIGHT</h4>985 <p>Special tokens like <code><start_function_call></code> have specific token IDs (e.g., token 48). The model uses these to understand structure.</p>986 </div>987 </div>988 </div>989 990 <!-- Lesson 2: Zero-Shot -->991 <div class="lesson-content" data-lesson="2">992 <h2 class="lesson-title">ZERO-SHOT FUNCTION CALLING (WHY IT FAILS)</h2>993 <div class="lesson-description">994 <p>Zero-shot means asking the model to do something without showing it an example. Let's see what happens!</p>995 996 <div class="error-box">997 <h4>THE PROBLEM</h4>998 <p>Without examples, FunctionGemma generates <code>error:</code> instead of <code>call:</code> after <code><start_function_call></code>.</p>999 </div>1000 1001 <div class="interactive-demo">1002 <h3>TEST ZERO-SHOT APPROACH</h3>1003 <input type="text" id="zeroShotQuery" value="What's the temperature in London?" placeholder="Enter your query...">1004 <button onclick="testZeroShot()">TEST ZERO-SHOT</button>1005 <div id="zeroShotOutput" class="output-area" style="margin-top: 15px;"></div>1006 </div>1007 1008 <div class="code-block">1009 <pre><span class="code-comment">// Zero-shot approach - NO examples provided</span>1010<span class="code-keyword">const</span> messages = [1011 {1012 role: <span class="code-string">"developer"</span>,1013 content: <span class="code-string">"You are a model that can do function calling..."</span>1014 },1015 {1016 role: <span class="code-string">"user"</span>,1017 content: <span class="code-string">"What's the temperature in London?"</span>1018 }1019 <span class="code-comment">// ❌ No example shown to the model!</span>1020];1021 1022<span class="code-comment">// Result: Model generates "error:" instead of "call:"</span>1023<span class="code-comment">// Token 1899 ("error") is chosen instead of token 6639 ("call")</span></pre>1024 </div>1025 1026 <div class="hint-box">1027 <h4>TOKEN ANALYSIS</h4>1028 <p>After <code><start_function_call></code> (token 48), the model's probability distribution favors token 1899 ("error") over token 6639 ("call") when no example is provided.</p>1029 </div>1030 </div>1031 </div>1032 1033 <!-- Lesson 3: One-Shot -->1034 <div class="lesson-content" data-lesson="3">1035 <h2 class="lesson-title">ONE-SHOT FUNCTION CALLING (PARTIAL SUCCESS)</h2>1036 <div class="lesson-description">1037 <p>One-shot means showing the model ONE example. Let's see if this helps!</p>1038 1039 <div class="interactive-demo">1040 <h3>TEST ONE-SHOT APPROACH</h3>1041 <input type="text" id="oneShotQuery" value="What's the temperature in Tokyo?" placeholder="Enter your query...">1042 <button onclick="testOneShot()">TEST ONE-SHOT</button>1043 <div id="oneShotOutput" class="output-area" style="margin-top: 15px;"></div>1044 </div>1045 1046 <div class="code-block">1047 <pre><span class="code-comment">// One-shot approach - ONE example provided</span>1048<span class="code-keyword">const</span> messages = [1049 {1050 role: <span class="code-string">"developer"</span>,1051 content: <span class="code-string">"You are a model that can do function calling..."</span>1052 },1053 {1054 role: <span class="code-string">"user"</span>,1055 content: <span class="code-string">"What's the temperature in Paris?"</span>1056 },1057 {1058 role: <span class="code-string">"assistant"</span>,1059 <span class="code-comment">// ✅ ONE example showing correct format</span>1060 content: <span class="code-string">"<start_function_call>call:get_current_temperature{location:<escape>Paris<escape>}<end_function_call>"</span>1061 },1062 {1063 role: <span class="code-string">"user"</span>,1064 content: <span class="code-string">"What's the temperature in Tokyo?"</span>1065 }1066];</pre>1067 </div>1068 1069 <div class="info-box">1070 <h4>RESULTS MAY VARY</h4>1071 <p>One-shot can work sometimes, but it's not as reliable as few-shot. The model needs more context to consistently generate correct function calls.</p>1072 </div>1073 </div>1074 </div>1075 1076 <!-- Lesson 4: Few-Shot -->1077 <div class="lesson-content" data-lesson="4">1078 <h2 class="lesson-title">FEW-SHOT FUNCTION CALLING (THE SOLUTION!)</h2>1079 <div class="lesson-description">1080 <p>Few-shot means showing the model multiple examples. This is the proven solution!</p>1081 1082 <div class="success-box">1083 <h4>THE SOLUTION</h4>1084 <p>By providing a few-shot example, we shift the model's token probabilities. Token 6639 ("call") becomes more likely than token 1899 ("error").</p>1085 </div>1086 1087 <div class="interactive-demo">1088 <h3>TEST FEW-SHOT APPROACH</h3>1089 <input type="text" id="fewShotQuery" value="What's the temperature in New York?" placeholder="Enter your query...">1090 <button onclick="testFewShot()">TEST FEW-SHOT</button>1091 <div id="fewShotOutput" class="output-area" style="margin-top: 15px;"></div>1092 </div>1093 1094 <div class="code-block">1095 <pre><span class="code-comment">// ✅ FEW-SHOT APPROACH (PROVEN TO WORK):</span>1096<span class="code-comment">// Add example conversation showing correct format</span>1097<span class="code-keyword">const</span> messages = [1098 {1099 role: <span class="code-string">"developer"</span>,1100 content: <span class="code-string">"You are a model that can do function calling with the following functions"</span>1101 },1102 {1103 role: <span class="code-string">"user"</span>,1104 content: <span class="code-string">"What's the temperature in Paris?"</span>1105 },1106 {1107 role: <span class="code-string">"assistant"</span>,1108 <span class="code-comment">// ✅ Example showing the EXACT format we want</span>1109 content: <span class="code-string">"<start_function_call>call:get_current_temperature{location:<escape>Paris<escape>}<end_function_call>"</span>1110 },1111 {1112 role: <span class="code-string">"user"</span>,1113 content: query <span class="code-comment">// Your actual query</span>1114 }1115];1116 1117<span class="code-comment">// Apply chat template with tools</span>1118<span class="code-keyword">const</span> inputs = <span class="code-function">await tokenizer</span>.apply_chat_template(messages, {1119 tools: [weatherFunction],1120 tokenize: <span class="code-keyword">true</span>,1121 add_generation_prompt: <span class="code-keyword">true</span>,1122 return_dict: <span class="code-keyword">true</span>1123});1124 1125<span class="code-comment">// Generate response</span>1126<span class="code-keyword">const</span> output = <span class="code-function">await model</span>.generate({1127 ...inputs,1128 max_new_tokens: <span class="code-keyword">512</span>,1129 do_sample: <span class="code-keyword">false</span>,1130 temperature: <span class="code-keyword">0.0</span>1131});1132 1133<span class="code-comment">// ✅ Result: Correct function call generated!</span>1134<span class="code-comment">// <start_function_call>call:get_current_temperature{location:<escape>New York<escape>}<end_function_call></span></pre>1135 </div>1136 1137 <div class="hint-box">1138 <h4>WHY FEW-SHOT WORKS</h4>1139 <ul style="margin-left: 20px; line-height: 2.5;">1140 <li>Shows the model the <strong>exact format</strong> we expect</li>1141 <li>Shifts token probabilities in favor of "call:" instead of "error:"</li>1142 <li>Provides context about the task structure</li>1143 <li>Works consistently with the quantized ONNX model</li>1144 </ul>1145 </div>1146 </div>1147 </div>1148 1149 <!-- Lesson 5: Token Analysis -->1150 <div class="lesson-content" data-lesson="5">1151 <h2 class="lesson-title">TOKEN-LEVEL DEEP DIVE</h2>1152 <div class="lesson-description">1153 <p>Let's examine what happens at the token level when the model generates function calls.</p>1154 1155 <div class="interactive-demo">1156 <h3>TOKEN-LEVEL ANALYSIS</h3>1157 <button onclick="analyzeTokens()">ANALYZE TOKEN GENERATION</button>1158 <div id="tokenAnalysisOutput" class="output-area" style="margin-top: 15px;"></div>1159 <div id="tokenVisualization" class="token-visualization" style="margin-top: 15px;"></div>1160 </div>1161 1162 <table class="comparison-table">1163 <thead>1164 <tr>1165 <th>TOKEN ID</th>1166 <th>TOKEN TEXT</th>1167 <th>CONTEXT</th>1168 <th>PROBABILITY SHIFT</th>1169 </tr>1170 </thead>1171 <tbody>1172 <tr>1173 <td>48</td>1174 <td><start_function_call></td>1175 <td>Always correct</td>1176 <td>N/A</td>1177 </tr>1178 <tr>1179 <td>1899</td>1180 <td>"error"</td>1181 <td>Zero-shot (no example)</td>1182 <td>❌ High probability</td>1183 </tr>1184 <tr>1185 <td>6639</td>1186 <td>"call"</td>1187 <td>Few-shot (with example)</td>1188 <td>✅ High probability</td>1189 </tr>1190 <tr>1191 <td>236787</td>1192 <td>":"</td>1193 <td>Always correct</td>1194 <td>N/A</td>1195 </tr>1196 </tbody>1197 </table>1198 1199 <div class="code-block">1200 <pre><span class="code-comment">// Token-level analysis of generated output</span>