Skip to content

Commit

Permalink
Add concurrency documentation and update promise queue implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
pelikhan committed Sep 25, 2024
1 parent dfaa700 commit 73f0cc9
Show file tree
Hide file tree
Showing 23 changed files with 99 additions and 103 deletions.
6 changes: 1 addition & 5 deletions docs/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions docs/src/content/docs/reference/scripts/concurrency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Concurrency
description: How to run multiple prompts concurrently
sidebar:
order: 50
---

When working with a GenAI, your program will likely be idling waiting for tokens to come back from the LLM.

## await and async

JavaScript has a wonderful support for non-blocking asynchronous APIs using [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function).

```js
// takes a while
async function workM() { ... }

// let other threads work while this function is running
await work()

Check failure on line 19 in docs/src/content/docs/reference/scripts/concurrency.md

View workflow job for this annotation

GitHub Actions / build

Incorrect function name; should be 'workM' instead of 'work'.
```

This feature is leveraged in [inline prompts](/genaiscript/reference/scripts/inline-prompts) to wait for a LLM result or run multiple queries concurrently.

## Serial vs concurrent execution

In this example, we run each LLM queries 'serially' using `await`:

```js
const poem = await prompt`write a poem`
const essay = await prompt`write an essay`
```

However, we can run all queries 'concurrently' to speed things up:

```js
const [poem, essay] = await Promise.all(
prompt`write a poem`,
prompt`write an essay`
)

Check failure on line 39 in docs/src/content/docs/reference/scripts/concurrency.md

View workflow job for this annotation

GitHub Actions / build

Missing function calls for 'prompt' template literals.
```

This works but it may become problematic if you have a lot of entries as you will create a lot of requests concurrently and probably hit some rate limiting boundaries.
Note that GenAIScript automatically limits the number of concurrent requests to a single model to prevent this scenario.

## Promise queue

The promise queue provides a way to run promises concurrently with a guaranteed concurrency limit, how many are allowed to run at the same time.
The difference with `Promise.all` is that you wrap each promise in a function.

```js
const queue = host.promiseQueue(3)
const res = await queue.all(
() => prompt`write a poem`
() => prompt`write an essay`
)

Check failure on line 55 in docs/src/content/docs/reference/scripts/concurrency.md

View workflow job for this annotation

GitHub Actions / build

Missing function calls for 'prompt' template literals.
```

Use the `mapAll` function to iterate over an array.

```js
const queue = host.promiseQueue(3)
const summaries = await queue.mapAll(
env.files,
(file) => prompt`Summarize ${file}`
)

Check failure on line 65 in docs/src/content/docs/reference/scripts/concurrency.md

View workflow job for this annotation

GitHub Actions / build

Missing function calls for 'prompt' template literals.
```
6 changes: 1 addition & 5 deletions genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/auto/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions packages/core/src/concurrency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ export function concurrentLimit(

export class PLimitPromiseQueue implements PromiseQueue {
private queue: LimitFunction
constructor(private readonly options: PromiseQueueOptions) {
this.queue = pLimit(
options?.concurrency ?? PROMISE_QUEUE_CONCURRENCY_DEFAULT
)
constructor(concurrency?: number) {
this.queue = pLimit(concurrency ?? PROMISE_QUEUE_CONCURRENCY_DEFAULT)
}

async mapAll<T extends unknown, Arguments extends unknown[], ReturnType>(
Expand Down
6 changes: 1 addition & 5 deletions packages/core/src/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/core/src/promptcontext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export async function createPromptContext(
await runtimeHost.select(message, options),
input: async (message) => await runtimeHost.input(message),
confirm: async (message) => await runtimeHost.confirm(message),
promiseQueue: (options) => new PLimitPromiseQueue(options),
promiseQueue: (concurrency) => new PLimitPromiseQueue(concurrency),
})

const ctx: PromptContext & RunPromptContextNode = {
Expand Down
6 changes: 1 addition & 5 deletions packages/core/src/types/prompt_template.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2306,10 +2306,6 @@ interface PromiseQueue {
): Promise<ReturnType[]>
}

Check failure on line 2307 in packages/core/src/types/prompt_template.d.ts

View workflow job for this annotation

GitHub Actions / build

The `mapAll` method in the `PromiseQueue` interface is missing a return type. It should specify that it returns a `Promise<ReturnType[]>`.

interface PromiseQueueOptions {
concurrency?: number
}

interface PromptHost extends ShellHost {
/**
* Starts a container
Expand All @@ -2320,7 +2316,7 @@ interface PromptHost extends ShellHost {
/**
* Create a new promise queue to run async functions with limited concurrency
*/
promiseQueue(options?: PromiseQueueOptions): PromiseQueue
promiseQueue(concurrency: number): PromiseQueue
}

interface ContainerHost extends ShellHost {
Expand Down
6 changes: 1 addition & 5 deletions packages/sample/genaisrc/blog/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/genaisrc/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/genaisrc/node/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/genaisrc/python/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/genaisrc/style/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/sample/genaisrc/summarize-concurrent.genai.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ script({
files: "src/rag/*",
})

const queue = host.promiseQueue({ concurrency: 2 })
const queue = host.promiseQueue(2)
const summaries = await queue.mapAll(env.files, (file) =>
runPrompt(
(_) => {
Expand Down
6 changes: 1 addition & 5 deletions packages/sample/src/aici/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/src/errors/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/src/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/src/makecode/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions packages/sample/src/tla/genaiscript.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 73f0cc9

Please sign in to comment.