Ana içeriğe geç

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()