যন্ত্রের ভাষায় বাস্তবতার কোনো অনুভূতি থাকে না। একটি টেক্সট তার কাছে শুধুই শূন্য ও একের সিরিজ, যতক্ষণ না আমরা তাকে অর্থপূর্ণ সংখ্যায় রূপ দিই — ঠিক এখানেই এম্বেডিং-এর প্রয়োজন। এই টিউটোরিয়ালে আমরা দেখব Spring AI ব্যবহার করে কীভাবে অতি সহজে টেক্সটকে সংখ্যা-ভেক্টরে রূপান্তরিত করা যায়, এবং সেই ভেক্টর ব্যবহার করেই গড়ে তোলা যায় সিম্যান্টিক সার্চ, রিকমেন্ডেশন ইঞ্জিন বা ডেটা ক্লাস্টারিং।

এম্বেডিং কী?

এম্বেডিং হলো কোনো টেক্সট বা শব্দের একটি সংখ্যাগত উপস্থাপন (নিউমেরিক্যাল রিপ্রেজেন্টেশন), যা সাধারণত উচ্চমাত্রার ভেক্টর আকারে থাকে। ধরুন, "বাংলা ভাষা সুন্দর" এই বাক্যটিকে ১৫৩৬টি দশমিক সংখ্যার একটি অ্যারে হিসেবে প্রকাশ করা হলো — এই অ্যারে-ই হচ্ছে তার এম্বেডিং। একই ভাষার বা একই অর্থের কাছাকাছি বাক্যগুলোর এম্বেডিং ভেক্টর স্পেসে পরস্পরের খুব নিকটে অবস্থান করে, আর বিপরীতার্থক বাক্যের ভেক্টরগুলো দূরে সরে থাকে।

এম্বেডিং-এর মূল শক্তি নিহিত এর অর্থ সংরক্ষণ ক্ষমতায়। দুটি বাক্য সম্পূর্ণ ভিন্ন শব্দে লিখলেও যদি তাদের মর্ম একই হয়, তবে তাদের ভেক্টর দূরত্ব (যেমন cosine similarity) ন্যূনতম হবে। বাস্তব অ্যাপ্লিকেশনে এটি ব্যবহার করে আমরা ডকুমেন্ট অনুসন্ধান, অনুচ্ছেদ শ্রেণিবিভাগ, সিমিলারিটি স্কোরিং, এবং এমনকি ছবি বা অডিওর সাথে টেক্সটের সম্পর্ক নির্ণয় করে থাকি। Spring AI-তে এম্বেডিং জেনারেশন একটি অত্যন্ত সরলীকৃত ধাপ, যা পরবর্তী সেকশনে আমরা বাস্তবায়ন করব।

Spring AI-তে এম্বেডিং কেন ব্যবহার করবেন?

Spring ইকোসিস্টেমের ডেভেলপারদের জন্য Spring AI এনেছে একটিমাত্র অ্যাবস্ট্রাকশন EmbeddingClient। আপনি চাইলেই একটি কনফিগারেশনের মাধ্যমে OpenAI, Azure OpenAI, Ollama, অথবা Amazon Bedrock-এর মতো বিভিন্ন প্রোভাইডারের এম্বেডিং মডেল ব্যবহার করতে পারেন — কোডের কোনো পরিবর্তন ছাড়াই। এই পোর্টেবিলিটি আপনার প্রোজেক্টকে ভবিষ্যতে অন্য কোনো মডেলে সরিয়ে নেওয়াকে করে দেয় ডিপেন্ডেন্সি-মুক্ত।

এছাড়া Spring AI-তে Document এবং VectorStore ইন্টারফেসের মাধ্যমে এম্বেডিং সংরক্ষণ ও অনুসন্ধান অত্যন্ত মসৃণ। আপনি পোস্টগ্রেসের মাধ্যমে pgvector, রেডিস, মিলভাস বা পাইনকোন-এর মতো ভেক্টর ডেটাবেস ব্যবহার করে বড় পরিসরের ডেটাসেটে মিলিসেকেন্ডে সিম্যান্টিক সার্চ চালাতে পারবেন। Spring-এর ডিপেন্ডেন্সি ইনজেকশন ও অটো-কনফিগারেশনের ফলে বয়লারপ্লেট কোডের বোঝা থাকছে না, আপনি সরাসরি ব্যবসায়িক লজিকে মনোযোগ দিতে পারেন।

Spring AI দিয়ে এম্বেডিং তৈরি ও ব্যবহার

প্রথমেই প্রোজেক্টে স্প্রিং এআই স্টার্টার যোগ করতে হবে। সাধারণত গ্র্যাডল বা ম্যাভেন ব্যবহার করলে নিচের মতো নির্ভরশীলতা যুক্ত হয়:

// build.gradle (Groovy DSL)
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'

এবার application.yml ফাইলে OpenAI-র API কী এবং মডেল সেটআপ দিন:

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      embedding:
        model: text-embedding-ada-002

এখন একটি সার্ভিস ক্লাসে EmbeddingClient ইনজেক্ট করে টেক্সটকে এম্বেডিং-এ রূপান্তর করুন। নিচের উদাহরণে দুটি বাংলা বাক্যের মধ্যে সিমিলারিটি মাপা হচ্ছে:

@Service
public class EmbeddingService {

    private final EmbeddingClient embeddingClient;

    public EmbeddingService(EmbeddingClient embeddingClient) {
        this.embeddingClient = embeddingClient;
    }

    public double compareSentences(String s1, String s2) {
        List<Double> vec1 = embeddingClient.embed(s1);
        List<Double> vec2 = embeddingClient.embed(s2);
        return cosineSimilarity(vec1, vec2);
    }

    private double cosineSimilarity(List<Double> a, List<Double> b) {
        double dot = 0.0, normA = 0.0, normB = 0.0;
        for (int i = 0; i < a.size(); i++) {
            dot += a.get(i) * b.get(i);
            normA += Math.pow(a.get(i), 2);
            normB += Math.pow(b.get(i), 2);
        }
        return dot / (Math.sqrt(normA) * Math.sqrt(normB));
    }
}

একইভাবে সম্পূর্ণ ডকুমেন্ট এম্বেড করতে চাইলে Document অবজেক্ট তৈরি করেও embed মেথড কল করতে পারেন। এরপর এম্বেডিংগুলিকে একটি VectorStore-এ জমা করে সার্ভ করা যায়। নিচের স্নিপেটে একটি ইন-মেমোরি ভেক্টর স্টোর ব্যবহার করে সার্চ দেখানো হলো:

@Bean
public VectorStore vectorStore(EmbeddingClient embeddingClient) {
    return new SimpleVectorStore(embeddingClient);
}

// ব্যবহার:
List<Document> docs = List.of(
    new Document("বাংলা শেখার সহজ উপায়"),
    new Document("কৃত্রিম বুদ্ধিমত্তা ও মেশিন লার্নিং")
);
vectorStore.add(docs);

List<Document> results = vectorStore.similaritySearch(
    SearchRequest.query("ভাষা শিক্ষা").withTopK(1)
);

মনে রাখবেন, VectorStore ইন্টারফেসের পেছনে আপনি চাইলে Redis, pgvector বা Chroma ড্রাইভারও ব্যবহার করতে পারেন — শুধু স্টার্টার বদলালেই হবে।

সর্বোত্তম চর্চা

  • মডেল নির্বাচন ও টোকেন লিমিট: বাংলা টেক্সটের জন্য ব্যবহার করুন মাল্টিলিঙ্গুয়াল মডেল যেমন text-embedding-3-small অথবা multilingual-e5-large। OpenAI-র মডেলগুলোতে টোকেন সীমা মাথায় রেখে বড় ডকুমেন্ট আগে ভেঙে ছোট ছোট চাঙ্কে (chunks) ভাগ করুন।
  • ব্যাচ প্রসেসিং: একক এপিআই কলে একাধিক টেক্সট এম্বেড করলে লেটেন্সি কমে এবং খরচ সাশ্রয় হয়। Spring AI-র embed(List<String>) বা embedBatched ব্যবহার করুন।
  • ভেক্টর নর্মালাইজেশন: কসাইন সিমিলারিটি ব্যবহারের আগে ভেক্টর নর্মালাইজ করে নিন। কিছু মডেল এমনিতেই নর্মালাইজড আউটপুট দেয়, কিন্তু না দিলে নিজে করে নেওয়াই নিরাপদ।
  • ক্যাশিং ও রেট-লিমিট: একবার তৈরি করা এম্বেডিং একটি ম্যাপে ক্যাশে রাখুন, যাতে বারবার একই টেক্সটের জন্য API ডাকা না লাগে। প্রোডাকশনে রেট-লিমিট ও খরচ ট্র্যাক করতে Micrometer মেট্রিক্স ইন্টিগ্রেট করুন।
  • ভেক্টর ডাটাবেসের ইন্ডেক্স: বড় ডেটাসেটে কসাইন দূরত্বের উপর ইনডেক্স তৈরি করে নিন। pgvector-এ ivfflat বা hnsw ইনডেক্স ব্যবহার করুন, যাতে অনুসন্ধান দ্রুত হয়।

সারাংশ

এম্বেডিং হচ্ছে আধুনিক ন্যাচারাল ল্যাঙ্গুয়েজ প্রসেসিং-এর ভিত্তি, এবং Spring AI সেই ক্ষমতাকে একজন স্প্রিং ডেভেলপারের হাতের মুঠোয় এনে দিয়েছে। একটি সহজ EmbeddingClient ইন্টারফেসের মাধ্যমে আপনি যে কোনো জায়ান্ট এআই মডেল ব্যবহার করতে পারছেন, ভেক্টর ডেটাবেসে তা সংরক্ষণ করে গড়ে তুলতে পারছেন ইন্টেলিজেন্ট সার্চ ও রিকমেন্ডেশন সিস্টেম। আজই আপনার স্প্রিং প্রোজেক্টে একটি পিওসি বানিয়ে দেখুন — একটি বাংলা বাক্য আরেকটি বাংলা বাক্যকে কত নিখুঁতভাবে খুঁজে নেয়।

Share