Text Generation
Transformers
Burmese
English
myanmar
burmese
llm
chat
instruction-following
conversational
autoregressive
Instructions to use amkyawdev/myanmar-ghost with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use amkyawdev/myanmar-ghost with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="amkyawdev/myanmar-ghost") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("amkyawdev/myanmar-ghost", dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use amkyawdev/myanmar-ghost with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "amkyawdev/myanmar-ghost" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amkyawdev/myanmar-ghost", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/amkyawdev/myanmar-ghost
- SGLang
How to use amkyawdev/myanmar-ghost with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "amkyawdev/myanmar-ghost" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amkyawdev/myanmar-ghost", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "amkyawdev/myanmar-ghost" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "amkyawdev/myanmar-ghost", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use amkyawdev/myanmar-ghost with Docker Model Runner:
docker model run hf.co/amkyawdev/myanmar-ghost
| """SHAP explainer for Myanmar Ghost model. | |
| Uses SHAP (SHapley Additive exPlanations) to explain | |
| individual predictions and word importance. | |
| """ | |
| import logging | |
| from pathlib import Path | |
| from typing import Any, Callable, Dict, List, Optional, Tuple, Union | |
| import numpy as np | |
| import shap | |
| import torch | |
| from tqdm import tqdm | |
| logger = logging.getLogger(__name__) | |
| class ThankingSHAPExplainer: | |
| """SHAP-based explainer for Myanmar text classification.""" | |
| def __init__( | |
| self, | |
| model, | |
| tokenizer, | |
| background_size: int = 100, | |
| device: str = "cuda" if torch.cuda.is_available() else "cpu", | |
| ): | |
| """ | |
| Args: | |
| model: PyTorch model or HuggingFace model | |
| tokenizer: Tokenizer for the model | |
| background_size: Number of background samples for SHAP | |
| device: Device to run on | |
| """ | |
| self.model = model | |
| self.tokenizer = tokenizer | |
| self.background_size = background_size | |
| self.device = device | |
| self.model.to(device) | |
| self.model.eval() | |
| self.explainer = None | |
| self.background_data = None | |
| def _get_tokenizer(self): | |
| """Get the tokenizer, handling both HF and custom tokenizers.""" | |
| if hasattr(self.tokenizer, "__call__"): | |
| return self.tokenizer | |
| return self.tokenizer.encode | |
| def _predict(self, texts: Union[List[str], np.ndarray]) -> np.ndarray: | |
| """Model prediction function for SHAP.""" | |
| if isinstance(texts, np.ndarray): | |
| texts = texts.tolist() | |
| # Tokenize | |
| if hasattr(self.tokenizer, "batch_encode_plus"): | |
| encoding = self.tokenizer.batch_encode_plus( | |
| texts, | |
| padding=True, | |
| truncation=True, | |
| max_length=128, | |
| return_tensors="pt", | |
| ) | |
| input_ids = encoding["input_ids"].to(self.device) | |
| attention_mask = encoding["attention_mask"].to(self.device) | |
| else: | |
| input_ids = torch.tensor( | |
| [self.tokenizer.encode(t) for t in texts] | |
| ).to(self.device) | |
| attention_mask = (input_ids != 0).long().to(self.device) | |
| with torch.no_grad(): | |
| outputs = self.model(input_ids, attention_mask) | |
| if hasattr(outputs, "logits"): | |
| logits = outputs.logits | |
| else: | |
| logits = outputs | |
| probs = torch.softmax(logits, dim=-1).cpu().numpy() | |
| return probs | |
| def fit_background( | |
| self, | |
| background_texts: List[str], | |
| ) -> None: | |
| """Fit background distribution for SHAP. | |
| Args: | |
| background_texts: List of texts to use as background | |
| """ | |
| logger.info(f"Fitting SHAP background with {len(background_texts)} samples") | |
| # Sample background if too large | |
| if len(background_texts) > self.background_size: | |
| indices = np.random.choice( | |
| len(background_texts), | |
| self.background_size, | |
| replace=False, | |
| ) | |
| background_texts = [background_texts[i] for i in indices] | |
| self.background_data = background_texts | |
| # Create SHAP explainer | |
| self.explainer = shap.Explainer( | |
| self._predict, | |
| self.tokenizer, | |
| output_names=["negative", "neutral", "positive", "sarcastic"], | |
| ) | |
| # Calculate background values | |
| logger.info("Computing SHAP values for background...") | |
| self.explainer(background_texts[:min(10, len(background_texts))]) | |
| logger.info("Background fitting complete") | |
| def explain( | |
| self, | |
| text: str, | |
| num_samples: int = 100, | |
| output_names: Optional[List[str]] = None, | |
| ) -> shap.Explanation: | |
| """Explain a single text. | |
| Args: | |
| text: Myanmar text to explain | |
| num_samples: Number of Monte Carlo samples | |
| output_names: Names for output classes | |
| Returns: | |
| SHAP Explanation object | |
| """ | |
| if self.explainer is None: | |
| logger.warning("No background data. Using default explainer.") | |
| self.explainer = shap.Explainer( | |
| self._predict, | |
| self.tokenizer, | |
| output_names=output_names or ["negative", "neutral", "positive", "sarcastic"], | |
| ) | |
| logger.info(f"Explaining text: {text[:50]}...") | |
| explainer = shap.Explainer( | |
| self._predict, | |
| self.tokenizer, | |
| output_names=output_names, | |
| ) | |
| shap_values = explainer([text]) | |
| return shap_values | |
| def explain_batch( | |
| self, | |
| texts: List[str], | |
| output_names: Optional[List[str]] = None, | |
| ) -> List[shap.Explanation]: | |
| """Explain multiple texts. | |
| Args: | |
| texts: List of Myanmar texts | |
| output_names: Names for output classes | |
| Returns: | |
| List of SHAP Explanation objects | |
| """ | |
| if output_names is None: | |
| output_names = ["negative", "neutral", "positive", "sarcastic"] | |
| explainer = shap.Explainer( | |
| self._predict, | |
| self.tokenizer, | |
| output_names=output_names, | |
| ) | |
| explanations = [] | |
| for text in tqdm(texts, desc="Explaining texts"): | |
| exp = explainer([text]) | |
| explanations.append(exp) | |
| return explanations | |
| def get_word_importance( | |
| self, | |
| text: str, | |
| class_index: int = 2, # positive by default | |
| ) -> List[Tuple[str, float]]: | |
| """Get word importance scores for a specific class. | |
| Args: | |
| text: Myanmar text | |
| class_index: Class index to explain | |
| Returns: | |
| List of (word, importance) tuples | |
| """ | |
| explanation = self.explain(text) | |
| # Get tokens and their SHAP values | |
| tokens = self.tokenizer.tokenize(text) | |
| shap_vals = explanation.values[0, :, class_index] | |
| # Handle tokenization differences | |
| if len(shap_vals) < len(tokens): | |
| # Pad if needed | |
| shap_vals = np.pad( | |
| shap_vals, | |
| (0, len(tokens) - len(shap_vals)), | |
| constant_values=0, | |
| ) | |
| elif len(shap_vals) > len(tokens): | |
| tokens = tokens + ["[PAD]"] * (len(shap_vals) - len(tokens)) | |
| # Create word-score pairs | |
| word_importance = list(zip(tokens, shap_vals.tolist())) | |
| # Sort by absolute importance | |
| word_importance.sort(key=lambda x: abs(x[1]), reverse=True) | |
| return word_importance | |
| def visualize_text( | |
| self, | |
| explanation: shap.Explanation, | |
| output_path: Optional[str] = None, | |
| ) -> None: | |
| """Visualize SHAP explanation as text. | |
| Args: | |
| explanation: SHAP explanation | |
| output_path: Optional path to save visualization | |
| """ | |
| text = explanation.data[0] if hasattr(explanation, "data") else "" | |
| output = f"\n{'='*60}\n" | |
| output += f"Text: {text}\n" | |
| output += f"{'='*60}\n" | |
| # Get top features for each class | |
| for i, class_name in enumerate(explanation.output_names): | |
| values = explanation.values[0, :, i] | |
| # Get top 5 words | |
| top_indices = np.argsort(np.abs(values))[-5:][::-1] | |
| output += f"\nClass: {class_name}\n" | |
| output += "-" * 40 + "\n" | |
| for idx in top_indices: | |
| if idx < len(text.split()): | |
| word = text.split()[idx] | |
| output += f" {word}: {values[idx]:.4f}\n" | |
| print(output) | |
| if output_path: | |
| with open(output_path, "w", encoding="utf-8") as f: | |
| f.write(output) | |
| logger.info(f"Visualization saved to {output_path}") | |
| class ThankingSHAPValues: | |
| """Compute SHAP values for thanking expression analysis.""" | |
| def __init__( | |
| self, | |
| model, | |
| tokenizer, | |
| class_names: List[str] = None, | |
| ): | |
| self.model = model | |
| self.tokenizer = tokenizer | |
| self.class_names = class_names or [ | |
| "genuine", "sarcastic", "complaining", "neutral" | |
| ] | |
| def compute_feature_importance( | |
| self, | |
| texts: List[str], | |
| feature_names: List[str], | |
| ) -> Dict[str, float]: | |
| """Compute SHAP-based feature importance. | |
| Args: | |
| texts: List of texts | |
| feature_names: Names of features to analyze | |
| Returns: | |
| Dictionary of feature importance scores | |
| """ | |
| import shap | |
| def predict_proba(texts: List[str]) -> np.ndarray: | |
| encoding = self.tokenizer.batch_encode_plus( | |
| texts, | |
| padding=True, | |
| truncation=True, | |
| max_length=128, | |
| return_tensors="pt", | |
| ) | |
| with torch.no_grad(): | |
| outputs = self.model( | |
| encoding["input_ids"], | |
| encoding["attention_mask"], | |
| ) | |
| probs = torch.softmax(outputs.logits, dim=-1) | |
| return probs.numpy() | |
| # Create simple background | |
| background = texts[:min(20, len(texts))] | |
| explainer = shap.Explainer(predict_proba, background) | |
| shap_values = explainer(texts[:5]) # Sample for speed | |
| # Aggregate importance | |
| importance = {} | |
| for i, feature in enumerate(feature_names): | |
| importance[feature] = np.mean( | |
| np.abs(shap_values.values[:, :, i]) | |
| ) | |
| return importance | |
| def analyze_sentence( | |
| self, | |
| text: str, | |
| ) -> Dict[str, Any]: | |
| """Analyze a single sentence with SHAP. | |
| Args: | |
| text: Myanmar text | |
| Returns: | |
| Analysis results including word importance | |
| """ | |
| import shap | |
| encoding = self.tokenizer( | |
| text, | |
| padding=True, | |
| truncation=True, | |
| max_length=128, | |
| return_tensors="pt", | |
| ) | |
| explainer = shap.Explainer( | |
| lambda x: self._predict_batch(x), | |
| self.tokenizer, | |
| ) | |
| explanation = explainer([text]) | |
| # Extract word-level importance | |
| tokens = self.tokenizer.convert_ids_to_tokens( | |
| encoding["input_ids"][0] | |
| ) | |
| result = { | |
| "text": text, | |
| "tokens": tokens, | |
| "prediction": explanation.output_names[ | |
| np.argmax(explanation.values[0].mean(axis=1)) | |
| ], | |
| "shap_values": explanation.values[0].tolist(), | |
| } | |
| return result | |
| def _predict_batch(self, texts: List[str]) -> np.ndarray: | |
| """Batch prediction for SHAP.""" | |
| encoding = self.tokenizer( | |
| texts, | |
| padding=True, | |
| truncation=True, | |
| max_length=128, | |
| return_tensors="pt", | |
| ) | |
| with torch.no_grad(): | |
| outputs = self.model( | |
| encoding["input_ids"], | |
| encoding["attention_mask"], | |
| ) | |
| probs = torch.softmax(outputs.logits, dim=-1) | |
| return probs.numpy() | |
| def create_shap_explainer( | |
| model, | |
| tokenizer, | |
| background_texts: Optional[List[str]] = None, | |
| ) -> ThankingSHAPExplainer: | |
| """Factory function to create SHAP explainer.""" | |
| explainer = ThankingSHAPExplainer(model, tokenizer) | |
| if background_texts: | |
| explainer.fit_background(background_texts) | |
| return explainer | |
| if __name__ == "__main__": | |
| print("ThankingSHAPExplainer loaded") | |
| print("Use create_shap_explainer() to create an explainer") | |