Skip to content

Commit

Permalink
Moving to GPT-4. (#582)
Browse files Browse the repository at this point in the history
* Moved to GPT-4 now that it is generally available.

* Added 'scalene' user.

* Added more robust code extraction logic. Bumped to GPT-4 (could possibly be an option in the UI, since 3.5 is much cheaper, though not as good).
  • Loading branch information
emeryberger authored Jul 25, 2023
1 parent 63af1fe commit 21be704
Showing 1 changed file with 79 additions and 29 deletions.
108 changes: 79 additions & 29 deletions scalene/scalene-gui/scalene-gui.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,34 +55,81 @@ function checkApiKey(apiKey) {
})();
}

function extractCode(text) {
/**
* Extracts code block from the given completion text.
*
* @param {string} text - A string containing text and other data.
* @returns {string} Extracted code block from the completion object.
*/
const lines = text.split('\n');
let i = 0;
while (i < lines.length && lines[i].trim() === '') {
i++;
}
const first_line = lines[i].trim();
let code_block;
if (first_line === '```') {
code_block = text.slice(3);
} else if (first_line.startsWith('```')) {
const word = first_line.slice(3).trim();
if (word.length > 0 && !word.includes(' ')) {
code_block = text.slice(first_line.length);
} else {
code_block = text;
}
} else {
code_block = text;
}
const end_index = code_block.indexOf('```');
if (end_index !== -1) {
code_block = code_block.slice(0, end_index);
}
return code_block;
}

async function sendPromptToOpenAI(prompt, len, apiKey) {
const endpoint = "https://api.openai.com/v1/completions";
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: "text-davinci-003",
prompt: prompt,
temperature: 0.3,
max_tokens: len,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
// 'response_format': 'url'
}),
});
const endpoint = "https://api.openai.com/v1/chat/completions";
const body = JSON.stringify({
// model: 'gpt-3.5-turbo',
model: 'gpt-4',
messages: [
{
role: 'system',
content: 'You are a Python programming assistant who ONLY responds with blocks of commented, optimized code. You never respond with text. Just code, starting with ``` and ending with ```.'
},
{
role: 'user',
content: prompt
}
],
temperature: 0.3,
frequency_penalty: 0,
presence_penalty: 0,
user: "scalene-user"
});

const data = await response.json();
// Chop off any blank lines in the header.
console.log(body);

const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: body,
});

try {
return data.choices[0].text.replace(/^\s*[\r\n]/gm, "");
} catch {
return "# Query failed.\n";
}
const data = await response.json();
// Chop off any blank lines in the header.

try {
// WAS (GPT-3): return data.choices[0].text.replace(/^\s*[\r\n]/gm, "");
return data.choices[0].message.content.replace(/^\s*[\r\n]/gm, "");
} catch {
return "# Query failed.\n";

}
}

function countSpaces(str) {
Expand All @@ -108,7 +155,7 @@ async function optimizeCode(imports, code, context) {
alert(
"To activate proposed optimizations, enter an OpenAI API key in advanced options."
);
return null;
return '';
}
// If the code to be optimized is just one line of code, say so.
let lineOf = " ";
Expand All @@ -129,13 +176,15 @@ async function optimizeCode(imports, code, context) {

const optimizePerformancePrompt = `Optimize the following${lineOf}Python code:\n\n${context}\n\n# Start of code\n\n${code}\n\n# End of code\n\nRewrite the above Python code only from "Start of code" to "End of code", to make it more efficient WITHOUT CHANGING ITS RESULTS. Assume the code has already executed all these imports; do NOT include them in the optimized code:\n\n${imports}\n\nUse native libraries if that would make it faster than pure Python. Consider using the following other libraries, if appropriate:\n\n${libraries}\n\nYour output should only consist of valid Python code. Output the resulting Python with brief explanations only included as comments prefaced with #. Include a detailed explanatory comment before the code, starting with the text "# Proposed optimization:". Make the code as clear and simple as possible, while also making it as fast and memory-efficient as possible. Use vectorized operations${useGPUstring}whenever it would substantially increase performance, and quantify the speedup in terms of orders of magnitude. Eliminate as many for loops, while loops, and list or dict comprehensions as possible, replacing them with vectorized equivalents. If the performance is not likely to increase, leave the code unchanged. Fix any errors in the optimized code. Optimized${lineOf}code:`

const pure_optimizePerformancePrompt = `Optimize the following${lineOf}Python code:\n\n${context}\n\n# Start of code\n\n${code}\n\n# End of code\n\nRewrite the above Python code only from "Start of code" to "End of code", to make it more efficient WITHOUT CHANGING ITS RESULTS. Assume the code has already executed all these imports; do NOT include them in the optimized code:\n\n${imports}\n\nONLY USE PURE PYTHON.\n\nYour output should only consist of valid Python code. Output the resulting Python with brief explanations only included as comments prefaced with #. Include a detailed explanatory comment before the code, starting with the text "# Proposed optimization:". Make the code as clear and simple as possible, while also making it as fast and memory-efficient as possible. If the performance is not likely to increase, leave the code unchanged. Fix any errors in the optimized code. Optimized${lineOf}code:`

const memoryEfficiencyPrompt = `Optimize the following${lineOf} Python code:\n\n${context}\n\n# Start of code\n\n${code}\n\n\n# End of code\n\nRewrite the above Python code only from "Start of code" to "End of code", to make it more memory-efficient WITHOUT CHANGING ITS RESULTS. Assume the code has already executed all these imports; do NOT include them in the optimized code:\n\n${imports}\n\nUse native libraries if that would make it more space efficient than pure Python. Consider using the following other libraries, if appropriate:\n\n${libraries}\n\nYour output should only consist of valid Python code. Output the resulting Python with brief explanations only included as comments prefaced with #. Include a detailed explanatory comment before the code, starting with the text "# Proposed optimization:". Make the code as clear and simple as possible, while also making it as fast and memory-efficient as possible. Use native libraries whenever possible to reduce memory consumption; invoke del on variables and array elements as soon as it is safe to do so. If the memory consumption is not likely to be reduced, leave the code unchanged. Fix any errors in the optimized code. Optimized${lineOf}code:`

const optimizePerf = document.getElementById('optimize-performance').checked;

let prompt;
if (optimizePerf) {
prompt = optimizePerformancePrompt;
prompt = optimizePerformancePrompt;
} else {
prompt = memoryEfficiencyPrompt;
}
Expand All @@ -148,8 +197,9 @@ async function optimizeCode(imports, code, context) {

// Use number of words in the original code as a proxy for the number of tokens.
const numWords = (code.match(/\b\w+\b/g)).length;

return await sendPromptToOpenAI(prompt, Math.max(numWords * 4, 500), apiKey);

const result = await sendPromptToOpenAI(prompt, Math.max(numWords * 4, 500), apiKey);
return extractCode(result);
}

function proposeOptimizationRegion(filename, file_number, lineno) {
Expand Down

0 comments on commit 21be704

Please sign in to comment.