Skip to content

Commit 46b4c29

Browse files
committed
refinements
1 parent d684dc4 commit 46b4c29

File tree

8 files changed

+121
-12
lines changed

8 files changed

+121
-12
lines changed

embeddings/clustering/sketch.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Programming A to Z
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
3+
14
// Function to load transformers.js dynamically
25
async function loadTransformers() {
36
try {

embeddings/comparison-matrix/sketch.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Programming A to Z
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
3+
14
// Function to load transformers.js dynamically
25
async function loadTransformers() {
36
try {

llms/chat-conversation/sketch.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Introduction to Machine Learning for the Arts
2-
// https://github.com/ml5js/Intro-ML-Arts-IMA-F24
1+
// Programming A to Z, Fall 2024
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
33

44
let conversationHistory = [];
55
let inputBox;
@@ -39,6 +39,7 @@ async function sendMessage() {
3939
try {
4040
// Generate a response based on the input prompt
4141
const output = await generator(conversationHistory, { max_new_tokens: 128 });
42+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at
4243
const reply = output[0].generated_text.at(-1).content;
4344
conversationHistory.push({ role: 'assistant', content: reply });
4445
chatLog = `Chatbot: ${reply}</br></br>` + chatLog;

llms/chat-prompt/sketch.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Introduction to Machine Learning for the Arts
2-
// https://github.com/ml5js/Intro-ML-Arts-IMA-F24
1+
// Programming A to Z
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
33

44
let generator;
55
let inputText;
@@ -15,8 +15,11 @@ async function setup() {
1515

1616
// Create a text generation pipeline with specific model and options
1717
generator = await pipeline('text-generation', 'onnx-community/Llama-3.2-1B-Instruct-q4f16', {
18-
dtype: 'q4',
18+
dtype: 'q4f16',
1919
device: 'webgpu',
20+
progress_callback: (x) => {
21+
console.log(x);
22+
},
2023
});
2124

2225
// Create a button after model is loaded
@@ -36,8 +39,10 @@ async function generateText() {
3639

3740
// Generate a response based on the input prompt
3841
const output = await generator(messages, { max_new_tokens: 128 });
42+
console.log(output);
3943

4044
// Extract and display the generated text
45+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at
4146
let outputText = output[0].generated_text.at(-1).content;
4247
background(240);
4348
text(outputText, 10, 10, width - 20, height - 20);

llms/text-completion/index.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.10.0/p5.js"></script>
5+
<meta charset="utf-8" />
6+
</head>
7+
<body>
8+
<main></main>
9+
<script src="tf-helper.js"></script>
10+
<script src="sketch.js"></script>
11+
</body>
12+
</html>

llms/text-completion/sketch.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Programming A to Z
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
3+
4+
let generator;
5+
let inputText;
6+
let outputText;
7+
8+
async function setup() {
9+
// Create a canvas and text input field
10+
createCanvas(400, 200);
11+
inputText = createInput('Type a prompt here...');
12+
13+
// Load the Transformers.js model pipeline with async/await
14+
let pipeline = await loadTransformers();
15+
16+
// Try
17+
// https://huggingface.co/HuggingFaceTB/SmolLM-135M
18+
// https://huggingface.co/HuggingFaceTB/SmolLM-360M
19+
20+
// Create a text generation pipeline with specific model and options
21+
generator = await pipeline('text-generation', 'HuggingFaceTB/SmolLM-135M', {
22+
dtype: 'q4',
23+
device: 'webgpu',
24+
progress_callback: (x) => {
25+
console.log(x);
26+
},
27+
});
28+
29+
// Create a button after model is loaded
30+
let button = createButton('Generate Text');
31+
button.mousePressed(generateText);
32+
}
33+
34+
// Asynchronous function to generate text based on user input
35+
async function generateText() {
36+
// Ensure the model is loaded
37+
if (generator) {
38+
// Complete the user's text
39+
const output = await generator(inputText.value(), { max_new_tokens: 128 });
40+
console.log(output);
41+
// Extract and display the generated text
42+
let outputText = output[0].generated_text;
43+
background(240);
44+
text(outputText, 10, 10, width - 20, height - 20);
45+
} else {
46+
// Log a message if the model is not yet loaded
47+
console.log('Model not loaded yet, try again in a minute.');
48+
}
49+
}

llms/text-completion/tf-helper.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
async function loadTransformers() {
2+
try {
3+
const module = await import(
4+
"https://cdn.jsdelivr.net/npm/@huggingface/[email protected]"
5+
);
6+
const { pipeline } = module;
7+
return pipeline;
8+
} catch (error) {
9+
console.error("Failed to load transformers.js", error);
10+
}
11+
}

whisper-demo/sketch.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
// Programming A to Z
2+
// https://github.com/Programming-from-A-to-Z/A2Z-F24
3+
4+
// Import the Transformers.js pipeline for speech recognition
15
import { pipeline } from 'https://cdn.jsdelivr.net/npm/@xenova/[email protected]';
26

37
let mediaRecorder;
@@ -6,69 +10,90 @@ let isRecording = false;
610
let transcriptDiv = document.getElementById('transcript');
711
let recordButton = document.getElementById('recordButton');
812

9-
// Downsample audio to 16000Hz
13+
// Function to downsample audio buffer to 16000Hz for Whisper model
1014
function downsampleAudioBuffer(buffer, targetSampleRate) {
1115
const sampleRate = buffer.sampleRate;
16+
17+
// If sample rate matches target, return original buffer
1218
if (sampleRate === targetSampleRate) {
1319
return buffer;
1420
}
21+
22+
// Calculate downsample ratio and new buffer length
1523
const ratio = sampleRate / targetSampleRate;
1624
const newLength = Math.round(buffer.length / ratio);
1725
const newBuffer = new Float32Array(newLength);
26+
27+
// Populate new buffer with downsampled audio data
1828
for (let i = 0; i < newLength; i++) {
1929
newBuffer[i] = buffer.getChannelData(0)[Math.round(i * ratio)];
2030
}
2131
return newBuffer;
2232
}
2333

34+
// Asynchronous function to transcribe audio using Whisper
2435
async function transcribeAudio(blob) {
36+
// Show transcribing status
2537
transcriptDiv.textContent = 'transcribing...';
38+
39+
// Load Whisper model from Transformers.js
2640
const model = await pipeline('automatic-speech-recognition', 'Xenova/whisper-tiny.en');
27-
// Convert Blob to ArrayBuffer
41+
42+
// Convert Blob to ArrayBuffer for audio decoding
2843
const arrayBuffer = await blob.arrayBuffer();
29-
// Use the Web Audio API to decode the ArrayBuffer into audio data
44+
45+
// Decode ArrayBuffer to audio data using Web Audio API
3046
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
3147
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
3248

33-
// Downsample audio to 16000Hz, as required by Whisper
49+
// Downsample the audio to 16000Hz as required by the model
3450
const downsampledAudio = downsampleAudioBuffer(audioBuffer, 16000);
3551

36-
// Perform transcription with Whisper
52+
// Perform transcription with Whisper model
3753
const result = await model(downsampledAudio);
3854

39-
// Display the transcription result
55+
// Display transcription result in the DOM
4056
transcriptDiv.textContent = result.text;
4157
}
4258

59+
// Function to start audio recording
4360
function startRecording() {
61+
// Request microphone access from the user
4462
navigator.mediaDevices
4563
.getUserMedia({ audio: true })
4664
.then((stream) => {
65+
// Initialize MediaRecorder with the audio stream
4766
mediaRecorder = new MediaRecorder(stream);
4867
mediaRecorder.start();
4968
isRecording = true;
5069
recordButton.textContent = 'stop recording';
70+
71+
// Collect audio data while recording
5172
mediaRecorder.ondataavailable = (event) => {
5273
audioChunks.push(event.data);
5374
};
54-
// Stop recording and transcribe the audio
75+
76+
// Stop recording and start transcription
5577
mediaRecorder.onstop = () => {
5678
const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });
5779
transcribeAudio(audioBlob);
5880
audioChunks = [];
5981
};
6082
})
6183
.catch((error) => {
84+
// Handle errors when accessing the microphone
6285
console.error('Error accessing microphone: ', error);
6386
});
6487
}
6588

89+
// Function to stop audio recording
6690
function stopRecording() {
6791
mediaRecorder.stop();
6892
isRecording = false;
6993
recordButton.textContent = 'start recording';
7094
}
7195

96+
// Event listener to toggle recording state
7297
recordButton.addEventListener('click', () => {
7398
if (isRecording) {
7499
stopRecording();

0 commit comments

Comments
 (0)