it:ai_delphi
Table of Contents
Artificial Intelligence using Delphi Programming Tool
see also:
- further reading on AI:
- DewResearch VCL for Delphi: tutorial on classification algorithms Naive Bayes, K nearest neighbors, Linear Classifier
Introduction
- Embarcadero's Delphi Rapid Application Design software allows very efficient and fast computing with easy modern graphic user interface design
- the Object Pascal programming language is relatively easy to learn being derived from Pascal, and in many ways resembles Python
- it is extremely extensible through its VCL and Firemonkey component frameworks
- there are now bidirectional support for Python libraries
Native Delphi Tools for AI
general mathematical and statistical analysis components
- Torry's listing of stats component packages: https://torry.net/components/science/statistic/
- ESBConsult (Australian developer): $AU228
- extensive maths and calendar libraries plus GUI edit components
- stats, 3D matrices and vectors
- currently VCL only
-
- Complex numbers, 3D vectors and tensors
- Universal algorithms for working with formulae of any complexity and for working with physics concepts
- calculation of special functions (Bessel, Legendre) and their derivatives
- least squares approximation of multidimensional data
- calculating definite integral values for one- and two- dimensional functions
- solving initial value problems for the systems of ordinary differential equations
- finding roots and extremums for univariate functions
- solving systems of nonlinear equations
-
- MtxVec - math engine for science and engineering
- Stats Master
- signal processing packages:
- DSP Master - advanced signal processing package
- FFT Properties - signal analyzer and recorder
- Optivec's MatrixLib Vector Matrices mathematics components €83 for educational use
- CUDA support only for C not Object Pascal as yet
accessing the GPU for advanced mathematical computation as in AI requirements
- moving data from RAM to GPU VRAM is expensive
- for mathematical functions such as sine or exponential functions, CUDA pays off from greater than 100,000 vector elements
- for matrix multiplication, payback occurs in the region of 200×200 elements
OpenCL
- open standard for accessing the GPU chip maintained by the Khronos working group and there is a large ecosystem
- uses IEEE 754 floating point format for consistent calculations
- most computers will have openCL.dll, openCL32.dll and openCL64.dll files already installed (even NVidia GPUs)
- need to build a kernel
Delphi native OpenCL components
- Mitov software
- included in Mitov Runtime
-
- their Cougar Open CL is included in MtxVec v5
CUDA
- NVidia proprietary interface to their GPU's
- CUDA kernels need to be written in C/C++ (Delphi language would need to be extended to be able to natively do this)
neural network architecture components
- Mitov neural networking components
- contains classifiers, training components, and a general purpose neuron component
- neural networks, self-organizing map, naive Bayes, K nearest neighbor, Radial Basis Function Network, Back propagation training, RProp training, Data preparation, Timing components
- fully compatible and directly integrates with Mitov's SignalLab, VideoLab, AudioLab, VisionLab, InstrumentLab, and PlotLab.
-
- “Data Miner package” - neural network components for classification algorithms: Naive Bayes, K nearest neighbors, Linear Classifier
- issues:
- no native library for the latest AI tools such as:
- the latest neural network architectures
Using Python libraries within Delphi
- this gives access to Python's amazing array of AI tools including CUDA and tensorflow
- HOWEVER, it has the downsides of using Python:
- requires a Python install on the local machine and all required Python libraries to be installed as per usual for Python
- Python code is by its nature slow to run being interpreted code not native executables
Using APIs from Delphi to access third party online AI tools
- avoids the need to install Python on local machines and the need to have powerful GPUs on local machines
- perhaps the preferred option for most applications
- see https://blogs.embarcadero.com/the-high-performance-future-of-ai-is-rest-apis/ examples using REST API's to access DeepAI
- https://blogs.embarcadero.com/this-api-adds-machine-learning-computer-vision-to-your-app/ accessing MS Cognitive Services on Azure for computer vision, etc via REST API
Gary Ayton's Delphi Perplexity API code
- see my app called perplexity with working code but their API has limitations as of March 2024:
- no GPT or Claude model available
- online version of sonar should not have a system prompt - the medium version does not seem to do well at diagnosis
- no citations currently available
- no ongoing conversation - each call has zero memory of prior calls
- costs money
- seems slower than their website calls
- their website does not have a Delphi example of accessing their API so I had to write one - see below:
procedure RunPerplexity(systemprompt, userprompt, model:String; var MemoResponse:TMemo);
var
zURL, response: String;
zJsonStreamIn, zJsonStreamOut: TStringStream;
NetHTTPClient: TNetHTTPClient;
NetHTTPRequest: TNetHTTPRequest;
i:Integer;
begin
zURL := 'https://api.perplexity.ai/chat/completions';
API_Key := 'MyAPIKey';
// Create a JSON object from the string
//perplexity request format: {"model":"mistral-7b-instruct","messages":[{"content":"string","role":"system"}],"max_tokens":0,"temperature":0.2,"top_p":0.9,"top_k":0,"stream":false,"presence_penalty":0,"frequency_penalty":1}
zJsonStreamIn := TStringStream.Create('{"model":"'+model+'","messages":[{"role":"system","content":"' + SystemPrompt + '"},{"role":"user","content":"' + UserPrompt + '"}]}');
try
zJsonStreamOut := TStringStream.Create;
try
NetHTTPClient := TNetHTTPClient.Create(nil);
try
NetHTTPRequest := TNetHTTPRequest.Create(nil);
try
MemoResponse.Lines.Clear;
application.ProcessMessages;
NetHTTPRequest.Client := NetHTTPClient;
NetHTTPRequest.URL := zURL;
NetHTTPRequest.MethodString := 'POST /chat/completions HTTP/1.1';
NetHTTPRequest.CustomHeaders['Authorization'] := 'Bearer ' + API_Key;
// Make the POST request and capture the response
NetHTTPRequest.Post(zURL, zJsonStreamIn, zJsonStreamOut);
// Display the response in a TMemo component:
try
// Extract the LLM response text from the response JSON object stream
response := ExtractContentFromJSON(zJsonStreamOut.DataString);
//now need to format the embedded line breaks:
i := pos(#$A, response); // #$A is = /n
try
MemoResponse.Lines.BeginUpdate; //prevent control visually updating each line add
while i > 0 do //create new lines for line breaks
begin
MemoResponse.Lines.Add(Copy(response,0,i-1));
response := Copy(response,i+1,length(response)-1);
i := pos(#$A, response);
end;
MemoResponse.Lines.Add(response);
//now scroll to top of memo:
MemoResponse.SelStart := 0;
MemoResponse.SelLength := 0;
MemoResponse.Perform(EM_SCROLLCARET, 0, 0);
finally
MemoResponse.Lines.EndUpdate;
end;
Except on E:exception do
begin
MemoResponse.Lines.Add('Error: '+#13+zJsonStreamOut.DataString);
end;
end;
finally
NetHTTPRequest.Free;
end;
finally
NetHTTPClient.Free;
end;
finally
zJsonStreamOut.Free;
end;
finally
zJsonStreamIn.Free;
end;
{
In this code:
- `TNetHTTPClient` is used to manage the HTTP requests.
- `TNetHTTPRequest` is used to configure and execute the specific POST request.
- The `CustomHeaders` property of `TNetHTTPRequest` is used to set the 'Authorization' header.
- The `Post` method of `TNetHTTPRequest` is used to send the request and receive the response.
Make sure to add `System.Net.HttpClient`, `System.Net.URLClient`, `System.Classes`, and `System.SysUtils` to the uses clause of your unit.
}
end;
function ExtractContentFromJSON(const AJSONText: string):String;
var
JSONValue, ChoicesArrayValue, ChoiceValue, MessageValue: TJSONValue;
JSONObj: TJSONObject;
JSONArray: TJSONArray;
begin
// Parse the JSON string into a JSONValue
JSONValue := TJSONObject.ParseJSONValue(AJSONText);
if JSONValue = nil then
raise Exception.Create('Invalid JSON string');
try
// Cast the JSONValue to a JSONObject
JSONObj := JSONValue as TJSONObject;
// Get the 'choices' array from the JSON object
ChoicesArrayValue := JSONObj.Values['choices'];
if ChoicesArrayValue = nil then
raise Exception.Create('Choices array not found');
// Cast the ChoicesArrayValue to a JSONArray
JSONArray := ChoicesArrayValue as TJSONArray;
// Get the first object from the 'choices' array
ChoiceValue := JSONArray.Items[0];
if ChoiceValue = nil then
raise Exception.Create('Choice object not found');
// Cast the ChoiceValue to a JSONObject
JSONObj := ChoiceValue as TJSONObject;
// Get the 'message' object from the choice
MessageValue := JSONObj.Values['message'];
if MessageValue = nil then
raise Exception.Create('Message object not found');
// Cast the MessageValue to a JSONObject
JSONObj := MessageValue as TJSONObject;
// Get the 'content' string from the 'message' object
result := JSONObj.Values['content'].Value;
finally
JSONValue.Free;
end;
end;
it/ai_delphi.txt · Last modified: 2024/04/01 09:37 by gary1