llama-cpp-hs-0.1.0.0: src/Llama/Adapter.hs
{- |
Module : Llama.Adapter
Description : Adapter interface for llama-cpp
Copyright : (c) 2025 Tushar Adhatrao
License : MIT
Maintainer : Tushar Adhatrao <tusharadhatrao@gmail.com>
-}
module Llama.Adapter (
initAdapterLora
, setAdapterLora
, rmAdapterLora
, clearAdapterLora
, applyAdapterCVec
) where
import Foreign
import Foreign.C.String
import Llama.Internal.Foreign
import Llama.Internal.Types
import Foreign.C (CFloat)
{- | Initialize a LoRA adapter from a file path.
This function wraps the C function 'llama_adapter_lora_init'
and returns a managed AdapterLora object.
-}
initAdapterLora :: Model -> FilePath -> IO (Either String AdapterLora)
initAdapterLora (Model modelFPtr) path = do
withForeignPtr modelFPtr $ \modelPtr -> do
withCString path $ \cPath -> do
adapter@(CLlamaAdapterLora adapterPtr) <-
c_llama_adapter_lora_init (CLlamaModel modelPtr) cPath
if adapter == CLlamaAdapterLora nullPtr
then return $ Left "Failed to initialize LoRA adapter"
else do
-- We directly use c_llama_adapter_lora_free as the finalizer
fp <- newForeignPtr p_llama_adapter_lora_free adapterPtr
return $ Right $ AdapterLora fp
-- | Apply a LoRA adapter with a given scale.
setAdapterLora :: Context -> AdapterLora -> Float -> IO (Either String ())
setAdapterLora (Context ctxFPtr) (AdapterLora adapterFPtr) scale = do
result <- withForeignPtr ctxFPtr $ \ctxPtr ->
withForeignPtr adapterFPtr $ \adapterPtr ->
c_llama_set_adapter_lora
(CLlamaContext ctxPtr)
(CLlamaAdapterLora adapterPtr)
(realToFrac scale)
if result == -1
then return $ Left "Failed to set LoRA adapter"
else return $ Right ()
-- | Remove a previously applied LoRA adapter.
rmAdapterLora :: Context -> AdapterLora -> IO (Either String ())
rmAdapterLora (Context ctxFPtr) (AdapterLora adapterFPtr) = do
result <- withForeignPtr ctxFPtr $ \ctxPtr ->
withForeignPtr adapterFPtr $ \adapterPtr ->
c_llama_rm_adapter_lora (CLlamaContext ctxPtr) (CLlamaAdapterLora adapterPtr)
if result == -1
then return $ Left "Failed to remove LoRA adapter"
else return $ Right ()
-- | Clear all active LoRA adapters from the context.
clearAdapterLora :: Context -> IO ()
clearAdapterLora (Context ctxFPtr) =
withForeignPtr ctxFPtr $ \ctxPtr ->
c_llama_clear_adapter_lora (CLlamaContext ctxPtr)
-- | Apply a context vector (cvec).
applyAdapterCVec :: Context -> Maybe [Float] -> Int -> Int -> Int -> IO (Either String ())
applyAdapterCVec (Context ctxFPtr) mValues n_embd il_start il_end = do
(ptr, len) <- case mValues of
Nothing -> pure (nullPtr, 0 :: Int)
Just vs -> do
arrayPtr <- floatArrayToPtr vs
pure (arrayPtr, length vs)
result <- withForeignPtr ctxFPtr $ \ctxPtr ->
c_llama_apply_adapter_cvec
(CLlamaContext ctxPtr)
ptr
(fromIntegral len)
(fromIntegral n_embd)
(fromIntegral il_start)
(fromIntegral il_end)
if result == -1
then return $ Left "Failed to apply context vector"
else return $ Right ()
floatArrayToPtr :: [Float] -> IO (Ptr CFloat)
floatArrayToPtr xs = do
ptr <- mallocBytes (length xs * sizeOf (undefined :: CFloat))
pokeArray ptr (map realToFrac xs)
return ptr