Ollama Nasıl Taklit Edilir?
Hey,
Bir Ollama sunucusunu taklit etmeye çalıştığım son denememden bazı kod parçacıklarını paylaşmak istedim.
create-llama ile çalışırken Ollama sunucusuna gönderilen sorguları ve ondan alınan yanıtları tam olarak yakalamam gerekiyordu. Bunu yapmak için sahte bir Ollama sunucusu oluşturdum. Ancak başlangıçta beklediğimden daha zorlu olduğu ortaya çıktı! :)
Tam olarak emin değilim ama denemem sırasında bir hata keşfetmiş olabileceğimi düşünüyorum! 🥳
Projeye kesinlikle biraz karmaşıklık katan sunucu iletişimini simüle etmek için Python'un soket modülünü kullandım. Bu yazıda yazdığım Python soket programını, süreç boyunca kullandığım diğer ilgili kod parçacıkları ve komutlarla birlikte paylaşacağım.
Bir süre curl ile denemeler yaptıktan sonra başlıkları ve yanıtları nasıl kullanacağımı buldum. Ancak verileri bir soket aracılığıyla parçalar halinde göndermek, beklediğim kadar kolay olmadı.
Ollama sunucusunun davranışını daha iyi anlamak için ayrıca aşağıdaki gibi birkaç komut da çalıştırdım:
curl -v http://localhost:11434/api/generate -d '{
"model": "llama3.2",
"prompt": "just say yes!"
}'
curl -v http://localhost:11434/api/embeddings -d '{
"model": "nomic-embed-text:latest",
"prompt": "merhaba",
"options":{"num_ctx":4096,"top_p":0.9,"temperature":0.7}
}'
İşte Ollama sunucusuna gönderilen ilk sorgu LlamaIndex:
Connection from ('127.0.0.1', 34094)
Received data: POST /api/embeddings HTTP/1.1
host: 127.0.0.1:11434
connection: keep-alive
Content-Type: application/json
Accept: application/json
User-Agent: ollama-js/0.5.10 (x64 linux Node.js/v20.18.0)
accept-language: *
sec-fetch-mode: cors
accept-encoding: gzip, deflate
content-length: 112
{"model":"mxbai-embed-large:latest","prompt":"merhaba","options":{"num_ctx":4096,"top_p":0.9,"temperature":0.7}}
Bir HTTP sunucusu kullanmak işleri çok daha basit hale getirecek olsa da, ham soketlerle ilgili zorlukların üstesinden gelmeye kendimi zorlamanın değerli bir öğrenme deneyimi olduğunu fark ettim. Bazen işleri zorlaştırmak daha iyi öğrenmeyi sağlayabilir! 😉
İşte geliştirdiğim Python soket programı:
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 11434))
server_socket.listen(5)
print("Server listening on port 11434")
while True:
conn, addr = server_socket.accept()
conn.settimeout(5)
print(f"Connection from {addr}")
try:
data = conn.recv(1024)
print(f"Received data: {data.decode()}")
# HTTP Response headers
response_headers = [
"HTTP/1.1 200 OK",
"Content-Type: application/x-ndjson",
"Date: Fri, 15 Nov 2024 15:46:59 GMT",
"Transfer-Encoding: chunked", # Telling the client to expect chunked transfer
]
# Send the headers
conn.sendall(("\r\n".join(response_headers) + "\r\n\r\n").encode())
# Chunked response data
chunks = [
'{"model":"llama3.2","created_at":"2024-11-15T15:46:15.027881945Z","response":"Yes","done":false}',
'{"model":"llama3.2","created_at":"2024-11-15T15:46:59.248901276Z","response":"","done":true,"done_reason":"stop","context":[128006,9125,128007,271,38766,1303,33025,2696,25,6790,220,2366,18,271,128009,128006,882,128007,271,4345,2019,10035,0,128009,128006,78191,128007,271,9642,13],"total_duration":242612055,"load_duration":31211312,"prompt_eval_count":29,"prompt_eval_duration":70000000,"eval_count":3,"eval_duration":139000000}',
]
# Sending chunks
for chunk in chunks:
chunk_size = hex(len(chunk))[2:] # Get chunk size in hex (removes '0x' prefix)
conn.sendall(f"{chunk_size}\r\n".encode()) # Send chunk size
conn.sendall(chunk.encode()) # Send the actual chunk data
conn.sendall(b"\r\n") # End of chunk (CRLF)
# Final chunk with size 0 to indicate end of data
conn.sendall(b"0\r\n\r\n") # End of chunked response
# Close the connection
conn.close()
except Exception as e:
print(f"Something went wrong: {e}")
conn.close()