Blog

Stream laziness in Tabby

Wayne Wang
Lucy Gao
Meng Zhang
September 30, 2023
4
-minute read

This blog focuses on understanding stream laziness in Tabby. You do not need to know this information to use the Tabby, but for those interested, it offers a deeper dive on why and how the Tabby handle its LLM workload.

What is streaming?

Let's begin by setting up a simple example program:

const express = require('express');

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function* llm() {
  let i = 1;
  while (true) {
    console.log(`producing ${i}`);
    yield i++;

    // Mimic LLM inference latency.
    await sleep(1000);
  }
}

function server(llm) {
  const app = express();
  app.get('/', async (req, res) => {
    res.writeHead(200, {
      'Content-Type': 'application/jsonstream',
      'Transfer-Encoding': 'chunked',
    });

    let value, done;
    do {
      ({ value, done } = await llm.next());
      res.write(JSON.stringify(value));
      res.write('\n');
    } while (!done);
  });

  app.listen(8080);
}

async function client() {
  const resp = await fetch('http://localhost:8080');

  // Read values from our stream
  const reader = resp.body.pipeThrough(new TextDecoderStream()).getReader();
  // We're only reading 3 items this time:
  for (let i = 0; i < 3; i++) {
    // we know our stream is infinite, so there's no need to check `done`.
    const { value } = await reader.read();
    console.log(`read ${value}`);
    await sleep(10ms);
  }
}

server(llm());
client();

In this example, we are creating an async generator to mimic a LLM that produces string tokens. We then create an HTTP endpoint that wraps the generator, as well as a client that reads values from the HTTP stream. It's important to note that our generator logs producing ${i}, and our client logs read ${value}. The LLM inference could take an arbitrary amount of time to complete, simulated by a 1000ms sleep in the generator.

Stream Laziness

If you were to run this program, you'd notice something interesting. We'll observe the LLM continuing to output producing ${i} even after the client has finished reading three times. This might seem obvious, given that the LLM is generating an infinite stream of integers. However, it represents a problem: our server must maintain an ever-expanding queue of items that have been pushed in but not pulled out.

Moreover, the workload involved in creating the stream is typically both expensive and time-consuming, such as computation workload on the GPU. But what if the client aborts the in-flight request due to a network issue or other intended behaviors?

This is where the concept of stream laziness comes into play. We should perform computations only when the client requests them. If the client no longer needs a response, we should halt production and pause the stream, thereby saving valuable GPU resources.

How to handle cancellation?

The core idea is straightforward: on the server side, we need to listen to the close event and check if the connection is still valid before pulling data from the LLM stream.

app.get('/', async (req, res) => {
  ...
  let canceled;
  req.on('close', () => canceled = true);
  do {
    ({ value, done } = await llm.next());
    ...
  } while (!done && !canceled);
});

Implement cancellation for Tabby

In Tabby, effective management of code completion cancellations is crucial for promptly responding to users' inputs while optimizing model usage to enhance performance.

On the client side, whenever we receive a new input from a user, it's essential to abort the previous query and promptly retrieve a new response from the server.

// Demo code in the client side

let controller;

const callServer = (prompt) => {
  controller = new AbortController();
  const signal = controller.signal;
  // 2. calling server API to get the result with the prompt
  const response = await fetch("/v1/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ prompt })
    signal
  });
}

const onChange = (e) => {
  if (controller) controller.abort(); // Abort the previous request
  callServer(e.target.value);
};

// 1. Debounce the input 100ms for example
<input onChange={debounce(onChange)} />

By employing streaming and implementing laziness semantics appropriately, all components operate smoothly and efficiently!

That's it

We would love to invite to join our Slack community! Please feel free to reach out to us on Slack - we have channels for discussing all aspects of the product and tech, and everyone is welcome to join the conversation.

Happy hacking 😁💪🏻

Share this post

Stay Updated with Tabby News

Subscribe to our newsletter for the latest updates and news about Tabby.

By joining, you agree to our Terms and Conditions.
Thank you! We've received your submission.
Oops! Something went wrong. Please try again.

Discover Tabby Unlock Your Coding Potential

Explore the Power of Tabby, the Self-Hosted AI Coding Assistant
                                                                                                             
                                                                                                             
                                                                                                             
                                                                                                             
333                                                                            333333                        
444   7                                                                       66466                          
00   313333                                                                 0000                             
   55555                                                                                                  331
  666                                                                                                    444 
888       777777                                                                                        888  
0       3311                                                                                            0    
    222222                                                                                                   
  455555         77777777                                                                                    
 666664       1111117                                                                                        
999999     3333333                                                                                    7      
8888     2222222   77777777                                                                    777           
000    5555555   1111111                                                                     33333           
0   4444444    1111113                                                                     55555             
  6666666    2333333                                                                      66664              
 999999    2222222                           7                                           8888                
888888    555555      77777777     77777777                                              00                  
0000   44444444     77777777    177777777                                                                    
00  4444444446   111111111    11111111                                                                       
0  666666666   13313131    3331313        777777                                                             
 999999999    333333     3333333        777777                                                               
8888888      222223    2222222        1111117                                                                
0000       222222     2222225      11111111                                                                  
000     55555555    5555555     333333333    7                                                               
0      5444444   544444445    3333322                                                                        
      444444   4444444444  2222222                                                             7             
      6666  66666666666 5552522   7 777   777 77    7 7   7                                  7               
     6666 66666666666  55555  7777777777  7777     7777   7777       7 7777       7 77 77 7      7 7   777   
   999999999999999    4444  7777777777 777777    177777  777777     777777  7777777777        7777 7777777   
 88898889888898     4444 111111111   111111     1111111  77777    777777 1777777777         717777777777     
88888888888        666 11111111    111111     11111111  11111    711111111111111          1111111111111      
0000000          666 3131313     3131313     11313133  11113    111111111111           111111111111111       
00000         9999  333333      3333333    33333333   13333   3333333333         333333333333333311          
000        999999  33333      3333333     333333     3333    3333333          33333333333333                 
0       8888888  222222    222222222    222222     3232    32332            3323232323223                    
    88888880    22222    222222222   2222222     2222    2222             2222222222222                      
 00000000     555555    55555555  255555552    2222    22222            222222222222                         
000000       55555    55555555 5555555555    5555   255555            5555555555552                          
0000       555555    555555555555555554    5555   55555555          555555555555                             
00      4444444     44444444444444445    44444 4444444445         44444444445                                
      44444444     444444444444444      444444444444 4444       4444444444                                   
    46666664      66666666666664       44444444644   444      46444444                                       
 66666666        6666666666666        666666666    6666      666666                                          
6969666        66969696969696       96666666     66666      66666     777777777    777777                    
99999        99999999999999       9999999      999999      99999     111111113    11111                      
99         999999999999        9999999        999999      99999    333333333     33333                       
         888888888      9988888888898       8888899     888889    22222222      22222   77777777             
      888888888      88888888888888      8888888     88888888   55555555       5555    111111                
    088888888      0888888888888       088888      88888888   444444444      44444    22222                  
  000000000      00000000000        000000      0000000000  666666666      66666    55555      1111111       
0000000000     000000000     00000000000    000000000000   99999999      999999    66666     2222222         
0 000000    000000000   0000000000000    0000000000000    8888888      888888   9999999    4444444           
000000    00000000    0000000000000   00000000000000     00000      0000000   0000000    89999998         7  
000    00000000     0000000000000   000000000000000    00000       000000   00000000    000000   9999999     
  

Get Started with our Community Plan Today

Get Started

Simple self-onboarding

Free community plan

Local-first deployment



  
333                                                                            333333                        
444   7                                                                       66466                          
00   313333                                                                 0000                             
   55555                                                                                                  331
  666                                                                                                    444 
888       777777                                                                                        888  
0       3311                                                                                            0    
    222222                                                                                                   
  455555         77777777                                                                                    
 666664       1111117                                                                                        
999999     3333333                                                                                    7      
8888     2222222   77777777                                                                    777           
000    5555555   1111111                                                                     33333           
0   4444444    1111113                                                                     55555             
  6666666    2333333                                                                      66664              
 999999    2222222                           7                                           8888                
888888    555555      77777777     77777777                                              00                  
0000   44444444     77777777    177777777                                                                    
00  4444444446   111111111    11111111                                                                       
0  666666666   13313131    3331313        777777                                                             
 999999999    333333     3333333        777777                                                               
8888888      222223    2222222        1111117                                                                
0000       222222     2222225      11111111                                                                  
000     55555555    5555555     333333333    7                                                               
0      5444444   544444445    3333322                                                                        
      444444   4444444444  2222222                                                             7             
      6666  66666666666 5552522   7 777   777 77    7 7   7                                  7               
     6666 66666666666  55555  7777777777  7777     7777   7777       7 7777       7 77 77 7      7 7   777   
   999999999999999    4444  7777777777 777777    177777  777777     777777  7777777777        7777 7777777   
 88898889888898     4444 111111111   111111     1111111  77777    777777 1777777777         717777777777     
88888888888        666 11111111    111111     11111111  11111    711111111111111          1111111111111      
0000000          666 3131313     3131313     11313133  11113    111111111111           111111111111111       
00000         9999  333333      3333333    33333333   13333   3333333333         333333333333333311          
000        999999  33333      3333333     333333     3333    3333333          33333333333333                 
0       8888888  222222    222222222    222222     3232    32332            3323232323223                    
    88888880    22222    222222222   2222222     2222    2222             2222222222222                      
 00000000     555555    55555555  255555552    2222    22222            222222222222                         
000000       55555    55555555 5555555555    5555   255555            5555555555552                          
0000       555555    555555555555555554    5555   55555555          555555555555                             
00      4444444     44444444444444445    44444 4444444445         44444444445                                
      44444444     444444444444444      444444444444 4444       4444444444                                   
    46666664      66666666666664       44444444644   444      46444444                                       
 66666666        6666666666666        666666666    6666      666666                                          
6969666        66969696969696       96666666     66666      66666     777777777    777777                    
99999        99999999999999       9999999      999999      99999     111111113    11111                      
99         999999999999        9999999        999999      99999    333333333     33333                       
         888888888      9988888888898       8888899     888889    22222222      22222   77777777             
      888888888      88888888888888      8888888     88888888   55555555       5555    111111                
    088888888      0888888888888       088888      88888888   444444444      44444    22222                  
  000000000      00000000000        000000      0000000000  666666666      66666    55555      1111111       
0000000000     000000000     00000000000    000000000000   99999999      999999    66666     2222222         
0 000000    000000000   0000000000000    0000000000000    8888888      888888   9999999    4444444           
000000    00000000    0000000000000   00000000000000     00000      0000000   0000000    89999998         7  
000    00000000     0000000000000   000000000000000    00000       000000   00000000    000000   9999999     

Explore Full Features with Team or Enterprise Plans

BOOK A DEMO 🚀

Enterprise-first experience

Flexible deployment options

Enhanced security support