diff --git "a/demo_usage.ipynb" "b/demo_usage.ipynb" --- "a/demo_usage.ipynb" +++ "b/demo_usage.ipynb" @@ -10,307 +10,416 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "f67fdbad", "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import sys\n", + "import os\n", + "from pathlib import Path\n", + "import importlib.util\n", + "import huggingface_hub\n", + "from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer\n", + "\n", + "def download_and_setup_model(model_name=\"gbyuvd/ChemMiniQ3-SAbRLo\", local_dir=\"./chemq3_model\"):\n", + " \"\"\"Download model files and set up the custom modules\"\"\"\n", + " \n", + " print(f\"๐Ÿ“ฅ Downloading model files from {model_name}...\")\n", + " \n", + " try:\n", + " # Download all files to a local directory\n", + " model_path = huggingface_hub.snapshot_download(\n", + " repo_id=model_name,\n", + " local_dir=local_dir,\n", + " local_files_only=False,\n", + " resume_download=True\n", + " )\n", + " \n", + " print(f\"โœ… Model downloaded to: {model_path}\")\n", + " \n", + " # List downloaded files\n", + " print(\"๐Ÿ“ Downloaded files:\")\n", + " for file in Path(model_path).iterdir():\n", + " if file.is_file():\n", + " print(f\" {file.name} ({file.stat().st_size} bytes)\")\n", + " \n", + " return Path(model_path)\n", + " \n", + " except Exception as e:\n", + " print(f\"โŒ Download failed: {e}\")\n", + " return None\n", + "\n", + "def load_custom_modules(model_path):\n", + " \"\"\"Load all the custom modules required by the model\"\"\"\n", + " \n", + " model_path = Path(model_path)\n", + " \n", + " # Add the model directory to Python path\n", + " if str(model_path) not in sys.path:\n", + " sys.path.insert(0, str(model_path))\n", + " \n", + " print(f\"๐Ÿ”ง Loading custom modules from {model_path}...\")\n", + " \n", + " # Required module files\n", + " required_files = {\n", + " 'configuration_chemq3mtp.py': 'configuration_chemq3mtp',\n", + " 'modeling_chemq3mtp.py': 'modeling_chemq3mtp', \n", + " 'FastChemTokenizerHF.py': 'FastChemTokenizerHF'\n", + " }\n", + " \n", + " loaded_modules = {}\n", + " \n", + " # Load each required module\n", + " for filename, module_name in required_files.items():\n", + " file_path = model_path / filename\n", + " \n", + " if not file_path.exists():\n", + " print(f\"โŒ Required file not found: {filename}\")\n", + " return None\n", + " \n", + " try:\n", + " spec = importlib.util.spec_from_file_location(module_name, file_path)\n", + " module = importlib.util.module_from_spec(spec)\n", + " \n", + " # Execute the module\n", + " spec.loader.exec_module(module)\n", + " loaded_modules[module_name] = module\n", + " \n", + " print(f\" โœ… Loaded {filename}\")\n", + " \n", + " except Exception as e:\n", + " print(f\" โŒ Failed to load {filename}: {e}\")\n", + " return None\n", + " \n", + " return loaded_modules\n", + "\n", + "def register_model_components(loaded_modules):\n", + " \"\"\"Register the model components with transformers\"\"\"\n", + " \n", + " print(\"๐Ÿ”— Registering model components...\")\n", + " \n", + " try:\n", + " # Get the classes from loaded modules\n", + " ChemQ3MTPConfig = loaded_modules['configuration_chemq3mtp'].ChemQ3MTPConfig\n", + " ChemQ3MTPForCausalLM = loaded_modules['modeling_chemq3mtp'].ChemQ3MTPForCausalLM\n", + " FastChemTokenizerSelfies = loaded_modules['FastChemTokenizerHF'].FastChemTokenizerSelfies\n", + " \n", + " # Register with transformers\n", + " AutoConfig.register(\"chemq3_mtp\", ChemQ3MTPConfig)\n", + " AutoModelForCausalLM.register(ChemQ3MTPConfig, ChemQ3MTPForCausalLM)\n", + " AutoTokenizer.register(ChemQ3MTPConfig, FastChemTokenizerSelfies)\n", + " \n", + " print(\"โœ… Model components registered successfully\")\n", + " \n", + " return ChemQ3MTPConfig, ChemQ3MTPForCausalLM, FastChemTokenizerSelfies\n", + " \n", + " except Exception as e:\n", + " print(f\"โŒ Registration failed: {e}\")\n", + " return None, None, None\n", + "\n", + "def load_model(model_path):\n", + " \"\"\"Load the model using the registered components\"\"\"\n", + " \n", + " print(\"๐Ÿš€ Loading model...\")\n", + " \n", + " try:\n", + " # Load config\n", + " config = AutoConfig.from_pretrained(str(model_path), trust_remote_code=False)\n", + " print(f\"โœ… Config loaded: {config.__class__.__name__}\")\n", + " \n", + " # Load model\n", + " model = AutoModelForCausalLM.from_pretrained(\n", + " str(model_path),\n", + " config=config,\n", + " torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,\n", + " trust_remote_code=False # We've already registered everything\n", + " )\n", + " print(f\"โœ… Model loaded: {model.__class__.__name__}\")\n", + " \n", + " # Load tokenizer\n", + " tokenizer = AutoTokenizer.from_pretrained(str(model_path), trust_remote_code=False)\n", + " print(f\"โœ… Tokenizer loaded: {tokenizer.__class__.__name__}\")\n", + " \n", + " return model, tokenizer, config\n", + " \n", + " except Exception as e:\n", + " print(f\"โŒ Model loading failed: {e}\")\n", + " import traceback\n", + " traceback.print_exc()\n", + " return None, None, None\n", + "\n", + "def test_model(model, tokenizer, config):\n", + " \"\"\"Test the loaded model\"\"\"\n", + " \n", + " print(\"\\n๐Ÿงช Testing model...\")\n", + " \n", + " # Setup device\n", + " device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + " print(f\"๐Ÿ–ฅ๏ธ Using device: {device}\")\n", + " \n", + " model = model.to(device)\n", + " model.eval()\n", + " \n", + " # Model info\n", + " print(f\"\\n๐Ÿ“Š Model Information:\")\n", + " print(f\" Model class: {model.__class__.__name__}\")\n", + " print(f\" Config class: {config.__class__.__name__}\")\n", + " print(f\" Tokenizer class: {tokenizer.__class__.__name__}\")\n", + " print(f\" Model type: {config.model_type}\")\n", + " print(f\" Vocab size: {config.vocab_size}\")\n", + " \n", + " # Set pad token if needed\n", + " if not hasattr(tokenizer, 'pad_token') or tokenizer.pad_token is None:\n", + " if hasattr(tokenizer, 'eos_token'):\n", + " tokenizer.pad_token = tokenizer.eos_token\n", + " print(\"โœ… Set pad_token to eos_token\")\n", + " \n", + " # Test tokenization\n", + " print(\"\\n๐Ÿ”ค Testing tokenization...\")\n", + " test_inputs = [\"[C][C][O]\", \"[C]\", \"[O]\"]\n", + " \n", + " for test_input in test_inputs:\n", + " try:\n", + " tokens = tokenizer(test_input, return_tensors=\"pt\")\n", + " print(f\" '{test_input}' -> {tokens.input_ids.tolist()}\")\n", + " except Exception as e:\n", + " print(f\" โŒ Tokenization failed for '{test_input}': {e}\")\n", + " continue\n", + " \n", + " # Test generation\n", + " print(\"\\n๐ŸŽฏ Testing generation...\")\n", + " test_prompts = [\"[C]\", \"[C][C]\"]\n", + " \n", + " for prompt in test_prompts:\n", + " try:\n", + " input_ids = tokenizer(prompt, return_tensors=\"pt\").input_ids.to(device)\n", + " \n", + " with torch.no_grad():\n", + " outputs = model.generate(\n", + " input_ids,\n", + " max_length=input_ids.shape[1] + 20,\n", + " temperature=0.8,\n", + " top_p=0.9,\n", + " top_k=50,\n", + " do_sample=True,\n", + " pad_token_id=tokenizer.pad_token_id if hasattr(tokenizer, 'pad_token_id') else 0,\n", + " num_return_sequences=3\n", + " )\n", + " \n", + " print(f\"\\n Prompt: '{prompt}'\")\n", + " for i, output in enumerate(outputs):\n", + " generated = tokenizer.decode(output, skip_special_tokens=True)\n", + " print(f\" {i+1}: {generated}\")\n", + " \n", + " except Exception as e:\n", + " print(f\" โŒ Generation failed for '{prompt}': {e}\")\n", + " \n", + " # Test MTP functionality if available\n", + " print(\"\\n๐Ÿ”ฌ Testing MTP functionality...\")\n", + " try:\n", + " if hasattr(model, 'set_mtp_training'):\n", + " print(\" โœ… MTP training methods available\")\n", + " if hasattr(model, 'generate_with_logprobs'):\n", + " print(\" โœ… MTP generation methods available\")\n", + " else:\n", + " print(\" โ„น๏ธ Standard model - no MTP methods detected\")\n", + " except Exception as e:\n", + " print(f\" โš ๏ธ MTP test error: {e}\")\n", + "\n", + "def main():\n", + " print(\"๐Ÿš€ ChemQ3-MTP Model Loader Starting...\\n\")\n", + " \n", + " model_name = \"gbyuvd/ChemMiniQ3-SAbRLo\"\n", + " local_dir = \"./chemq3_model\"\n", + " \n", + " # Step 1: Download model files\n", + " model_path = download_and_setup_model(model_name, local_dir)\n", + " if model_path is None:\n", + " return None, None, None\n", + " \n", + " print()\n", + " \n", + " # Step 2: Load custom modules\n", + " loaded_modules = load_custom_modules(model_path)\n", + " if loaded_modules is None:\n", + " return None, None, None\n", + " \n", + " print()\n", + " \n", + " # Step 3: Register components\n", + " config_class, model_class, tokenizer_class = register_model_components(loaded_modules)\n", + " if config_class is None:\n", + " return None, None, None\n", + " \n", + " print()\n", + " \n", + " # Step 4: Load the model\n", + " model, tokenizer, config = load_model(model_path)\n", + " if model is None:\n", + " return None, None, None\n", + " \n", + " # Step 5: Test the model\n", + " test_model(model, tokenizer, config)\n", + " \n", + " print(\"\\n๐ŸŽ‰ Model loading and testing completed successfully!\")\n", + " \n", + " return model, tokenizer, config\n", + "\n", + "if __name__ == \"__main__\":\n", + " model, tokenizer, config = main()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b2ea169c", + "metadata": {}, + "outputs": [], + "source": [ + "# Generate SELFIES\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model.to(device)\n", + "input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", + "gen = model.generate(input_ids, max_length=256, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", + "print(tokenizer.decode(gen[0], skip_special_tokens=True))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bcd4f1fa", + "metadata": {}, + "outputs": [], + "source": [ + "# Manually convert it to SMILES\n", + "import selfies as sf\n", + "\n", + "test = tokenizer.decode(gen[0], skip_special_tokens=True)\n", + "test = test.replace(' ', '')\n", + "print(sf.decoder(test))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eaf273a0", + "metadata": {}, + "outputs": [], + "source": [ + "# Generate Mol Viz\n", + "from rdkit import Chem\n", + "from rdkit.Chem import Draw\n", + "\n", + "input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", + "gen = model.generate(input_ids, max_length=25, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", + "generatedmol = tokenizer.decode(gen[0], skip_special_tokens=True)\n", + "\n", + "test = generatedmol.replace(' ', '')\n", + "csmi_gen = sf.decoder(test)\n", + "print(csmi_gen)\n", + "mol = Chem.MolFromSmiles(csmi_gen)\n", + "\n", + "# Draw the molecule\n", + "Draw.MolToImage(mol)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "3f68f519", + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "๐Ÿš€ ChemQ3-MTP Model Loader Starting...\n", - "\n", - "๐Ÿ“ฅ Downloading model files from gbyuvd/ChemMiniQ3-SAbRLo...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "d:\\ProgramData\\miniconda3\\Lib\\site-packages\\huggingface_hub\\file_download.py:945: FutureWarning: `resume_download` is deprecated and will be removed in version 1.0.0. Downloads always resume when possible. If you want to force a new download, use `force_download=True`.\n", - " warnings.warn(\n" + "Using MTP-specific generation...\n", + "Generated SELFIES: .[C][N][C][Branch1][#C][S][C][C][=Branch1][C][=O][C][=C][C][=C][C][=C][Ring1][=Branch1][=N][N][=C][Ring1][#C][C][C][=C][O][C][=Ring1][Branch1][C]\n", + "Decoded SMILES: CN1C(SCC(=O)C2=CC=CC=C2)=NN=C1C=3C=COC=3C\n" ] }, { "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "1859ad9097334d0f9a426bba84277c98", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Fetching 17 files: 0%| | 0/17 [00:00" ] }, "metadata": {}, "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "โœ… Model downloaded to: D:\\tempo\\chemq3_model\n", - "๐Ÿ“ Downloaded files:\n", - " .gitattributes (1519 bytes)\n", - " config.json (1161 bytes)\n", - " configuration_chemq3mtp.py (876 bytes)\n", - " demo_usage.ipynb (36582 bytes)\n", - " FastChemTokenizerHF.py (28659 bytes)\n", - " generation_config.json (174 bytes)\n", - " model.safetensors (39437252 bytes)\n", - " modeling_chemq3mtp.py (18125 bytes)\n", - " README.md (8849 bytes)\n", - " rl_utils.py (20726 bytes)\n", - " tokenizer_config.json (302 bytes)\n", - " trainer.py (2417 bytes)\n", - " trainer_state.json (806 bytes)\n", - " training_args.bin (5368 bytes)\n", - " training_config.json (252 bytes)\n", - " vocab.json (21574 bytes)\n", - " __init__.py (569 bytes)\n", - "\n", - "๐Ÿ”ง Loading custom modules from D:\\tempo\\chemq3_model...\n", - " โœ… Loaded configuration_chemq3mtp.py\n" - ] - }, + } + ], + "source": [ + "# Generate Mol Viz with MTP-specific generation\n", + "from rdkit import Chem\n", + "from rdkit.Chem import Draw\n", + "import selfies as sf\n", + "import torch\n", + "\n", + "# Setup device first\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "\n", + "# Check if MTP-specific generation is available\n", + "if hasattr(model, 'generate_with_logprobs'):\n", + " print(\"Using MTP-specific generation...\")\n", + " input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", + " \n", + " # Try MTP-specific generation with log probabilities\n", + " try:\n", + " outputs = model.generate_with_logprobs(\n", + " input_ids,\n", + " max_new_tokens=25, # Correct parameter name\n", + " temperature=1,\n", + " top_k=50,\n", + " do_sample=True,\n", + " return_probs=True, # This returns action probabilities\n", + " tokenizer=tokenizer # Pass tokenizer for decoding\n", + " )\n", + " \n", + " # Handle the output (returns: decoded_list, logprobs, tokens, probs)\n", + " gen = outputs[2] # Get the generated token IDs (index 2)\n", + " except Exception as e:\n", + " print(f\"MTP generation failed: {e}, falling back to standard generation\")\n", + " gen = model.generate(input_ids, max_length=25, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", + "else:\n", + " print(\"Using standard generation...\")\n", + " input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", + " gen = model.generate(input_ids, max_length=25, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", + "\n", + "# Decode and process the generated molecule\n", + "generatedmol = tokenizer.decode(gen[0], skip_special_tokens=True)\n", + "test = generatedmol.replace(' ', '')\n", + "csmi_gen = sf.decoder(test)\n", + "print(f\"Generated SELFIES: {test}\")\n", + "print(f\"Decoded SMILES: {csmi_gen}\")\n", + "\n", + "mol = Chem.MolFromSmiles(csmi_gen)\n", + "\n", + "# Draw the molecule\n", + "if mol is not None:\n", + " img = Draw.MolToImage(mol)\n", + " display(img) # Use display() in Jupyter notebooks\n", + "else:\n", + " print(\"โŒ Could not create molecule from generated SMILES\")\n" + ] + }, + { + "cell_type": "markdown", + "id": "b16c5461", + "metadata": {}, + "source": [ + "# Testing MTP Head Generation (Local)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cefc1a68", + "metadata": {}, + "outputs": [ { "name": "stderr", "output_type": "stream", @@ -322,12 +431,27 @@ "name": "stdout", "output_type": "stream", "text": [ + "๐Ÿš€ ChemQ3-MTP Model Loader Starting...\n", + "\n", + "๐Ÿ“ Loading library from: ./ChemQ3MTP\n", + "๐Ÿ”ง Loading custom modules from ChemQ3MTP...\n", + " โœ… Loaded configuration_chemq3mtp.py\n", " โœ… Loaded modeling_chemq3mtp.py\n", " โœ… Loaded FastChemTokenizerHF.py\n", "\n", "๐Ÿ”— Registering model components...\n", "โœ… Model components registered successfully\n", "\n", + "๐Ÿ“ Loading model weights from checkpoint: ./chunk-4/\n", + "๐Ÿ“ Checkpoint files:\n", + " config.json (1161 bytes)\n", + " generation_config.json (174 bytes)\n", + " model.safetensors (39437252 bytes)\n", + " tokenizer_config.json (302 bytes)\n", + " training_args.bin (5368 bytes)\n", + " training_config.json (248 bytes)\n", + " vocab.json (21574 bytes)\n", + "\n", "๐Ÿš€ Loading model...\n", "โœ… Config loaded: ChemQ3MTPConfig\n", "โœ… Model loaded: ChemQ3MTPForCausalLM\n", @@ -351,14 +475,14 @@ "๐ŸŽฏ Testing generation...\n", "\n", " Prompt: '[C]'\n", - " 1: [C] [#C] [#C] [C] [#C] [C] [#C] [C]\n", - " 2: [C] [P] [#C] [=C] [Branch1] [=Branch2] [C] [=C] [C] [=C] [C] [=C] [Ring1] [=Branch1] [N] [Branch1] [=C] [C] [=C] [Ring1] [#Branch2] [C] [=C] [C] [=C] [C] [=C] [Ring1] [=Branch1] [C] [C]\n", - " 3: [C] [Branch1] [Ring2] [C] [Ring1] [Branch1] [C] [Ring1] [Ring2] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [=C] [C] [=C] [Branch1] [C] [Br] [C] [=C] [Ring1] [#Branch1]\n", + " 1: [C] [Ring1] [Ring1] [Branch1] [C] [Cl] [Cl]\n", + " 2: [C] .[Cl]\n", + " 3: [C] .[O] [C] [C] [N] [C] [C] [C] [C] [C] [C] [C] [C] [N] [C] [C] [=C] [C] [=C] [Branch1] [=Branch2] [C] [=C] [C] [=C] [C] [=C] [Ring1] [=Branch1] [C] [=C] [Ring1] [N]\n", "\n", " Prompt: '[C][C]'\n", - " 1: [C] [C] [O] [P] [=Branch1] [C] [=O] [Branch1] [C] [O] [O]\n", - " 2: [C] [C] [Ring2] [Ring2] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [C] [Branch1] [C] [C] [C]\n", - " 3: [C] [C] [=C] [Branch1] [Ring1] [C] [C] [C] [C] [C] [C] [C] [C]\n", + " 1: [C] [C] .[C] [C] [C] [N] [Branch1] [Ring2] [C] [C] [C] [C] [C] [C] [N] [C] [=Branch1] [C] [=O] [C] [=C] [C] [C] [=Branch1] [C] [=O] [N] [Branch1] [C] [C] [C] [=C] [C] [=C] [C] [=C] [Ring1] [=Branch1] [C] [=Ring1] [N] [N] [Ring1] [#C] [C]\n", + " 2: [C] [C]\n", + " 3: [C] [C]\n", "\n", "๐Ÿ”ฌ Testing MTP functionality...\n", " โœ… MTP training methods available\n", @@ -374,47 +498,18 @@ "import os\n", "from pathlib import Path\n", "import importlib.util\n", - "import huggingface_hub\n", "from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer\n", "\n", - "def download_and_setup_model(model_name=\"gbyuvd/ChemMiniQ3-SAbRLo\", local_dir=\"./chemq3_model\"):\n", - " \"\"\"Download model files and set up the custom modules\"\"\"\n", - " \n", - " print(f\"๐Ÿ“ฅ Downloading model files from {model_name}...\")\n", - " \n", - " try:\n", - " # Download all files to a local directory\n", - " model_path = huggingface_hub.snapshot_download(\n", - " repo_id=model_name,\n", - " local_dir=local_dir,\n", - " local_files_only=False,\n", - " resume_download=True\n", - " )\n", - " \n", - " print(f\"โœ… Model downloaded to: {model_path}\")\n", - " \n", - " # List downloaded files\n", - " print(\"๐Ÿ“ Downloaded files:\")\n", - " for file in Path(model_path).iterdir():\n", - " if file.is_file():\n", - " print(f\" {file.name} ({file.stat().st_size} bytes)\")\n", - " \n", - " return Path(model_path)\n", - " \n", - " except Exception as e:\n", - " print(f\"โŒ Download failed: {e}\")\n", - " return None\n", - "\n", - "def load_custom_modules(model_path):\n", - " \"\"\"Load all the custom modules required by the model\"\"\"\n", + "def load_custom_modules(library_path):\n", + " \"\"\"Load all the custom modules required by the model from library directory\"\"\"\n", " \n", - " model_path = Path(model_path)\n", + " library_path = Path(library_path)\n", " \n", - " # Add the model directory to Python path\n", - " if str(model_path) not in sys.path:\n", - " sys.path.insert(0, str(model_path))\n", + " # Add the library directory to Python path\n", + " if str(library_path) not in sys.path:\n", + " sys.path.insert(0, str(library_path))\n", " \n", - " print(f\"๐Ÿ”ง Loading custom modules from {model_path}...\")\n", + " print(f\"๐Ÿ”ง Loading custom modules from {library_path}...\")\n", " \n", " # Required module files\n", " required_files = {\n", @@ -427,7 +522,7 @@ " \n", " # Load each required module\n", " for filename, module_name in required_files.items():\n", - " file_path = model_path / filename\n", + " file_path = library_path / filename\n", " \n", " if not file_path.exists():\n", " print(f\"โŒ Required file not found: {filename}\")\n", @@ -585,36 +680,54 @@ "def main():\n", " print(\"๐Ÿš€ ChemQ3-MTP Model Loader Starting...\\n\")\n", " \n", - " model_name = \"gbyuvd/ChemMiniQ3-SAbRLo\"\n", - " local_dir = \"./chemq3_model\"\n", + " # Library directory (contains the .py files)\n", + " library_dir = \"./ChemQ3MTP\"\n", " \n", - " # Step 1: Download model files\n", - " model_path = download_and_setup_model(model_name, local_dir)\n", - " if model_path is None:\n", + " # Check if library directory exists\n", + " if not Path(library_dir).exists():\n", + " print(f\"โŒ Library directory does not exist: {library_dir}\")\n", " return None, None, None\n", " \n", - " print()\n", + " print(f\"๐Ÿ“ Loading library from: {library_dir}\")\n", " \n", - " # Step 2: Load custom modules\n", - " loaded_modules = load_custom_modules(model_path)\n", + " # Load custom modules from library directory\n", + " loaded_modules = load_custom_modules(Path(library_dir))\n", " if loaded_modules is None:\n", " return None, None, None\n", " \n", " print()\n", " \n", - " # Step 3: Register components\n", + " # Register components\n", " config_class, model_class, tokenizer_class = register_model_components(loaded_modules)\n", " if config_class is None:\n", " return None, None, None\n", " \n", " print()\n", " \n", - " # Step 4: Load the model\n", - " model, tokenizer, config = load_model(model_path)\n", + " # Load model from checkpoint directory\n", + " checkpoint_dir = \"./chunk-4/\"\n", + " \n", + " # Check if checkpoint directory exists\n", + " if not Path(checkpoint_dir).exists():\n", + " print(f\"โŒ Checkpoint directory does not exist: {checkpoint_dir}\")\n", + " return None, None, None\n", + " \n", + " print(f\"๐Ÿ“ Loading model weights from checkpoint: {checkpoint_dir}\")\n", + " \n", + " # List checkpoint files\n", + " print(\"๐Ÿ“ Checkpoint files:\")\n", + " for file in Path(checkpoint_dir).iterdir():\n", + " if file.is_file():\n", + " print(f\" {file.name} ({file.stat().st_size} bytes)\")\n", + " \n", + " print()\n", + " \n", + " # Load the model from checkpoint\n", + " model, tokenizer, config = load_model(Path(checkpoint_dir))\n", " if model is None:\n", " return None, None, None\n", " \n", - " # Step 5: Test the model\n", + " # Test the model\n", " test_model(model, tokenizer, config)\n", " \n", " print(\"\\n๐ŸŽ‰ Model loading and testing completed successfully!\")\n", @@ -625,116 +738,10 @@ " model, tokenizer, config = main()" ] }, - { - "cell_type": "markdown", - "id": "cf544bee", - "metadata": {}, - "source": [ - "# Ordinary Generate" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b2ea169c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[O] [C] [=C] [C] [=C] [Branch1] [C] [Cl] [C] [=C] [Ring1] [#Branch1] [C] [=C] [C] [C] [Branch1] [=N] [C] [=C] [C] [=C] [C] [=C] [Ring1] [=Branch1] [N] [C] [Ring1] [=N] [=O] [C] [Ring1] [S] [C] [=C] [C] [=C] [Branch1] [Ring1] [O] [C] [C] [=C] [Ring1] [Branch2]\n" - ] - } - ], - "source": [ - "# Generate SELFIES\n", - "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", - "model.to(device)\n", - "input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", - "gen = model.generate(input_ids, max_length=256, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", - "print(tokenizer.decode(gen[0], skip_special_tokens=True))" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "bcd4f1fa", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "OC1=CC=C(Cl)C=C1C=CCC(C2=CC=CC=C2NC)=O\n" - ] - } - ], - "source": [ - "# Manually convert it to SMILES\n", - "import selfies as sf\n", - "\n", - "test = tokenizer.decode(gen[0], skip_special_tokens=True)\n", - "test = test.replace(' ', '')\n", - "print(sf.decoder(test))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "eaf273a0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "OC=C1C=CC(OC)=C1OCCCNCC2=CC=CC=C2C\n" - ] - }, - { - "data": { - "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAKF7qi2t1HaRWs93cyIZPKg2gqgIG4lmAHJx1yfwNMsdctdQuI4IklWR43ch1AKFHCMrc/eBP0460y+tLyLVF1Ox8mRxAYZYpmZQy53AgqCcjnjBzntWHoOkWOtJbaw7W99bzJOzFoyB5jy5OAegGCOeaxcpc1kehCjQdHnl9/nrp26ad/wAuosL2PULQXESuqF3TDgZyrFT+oNWaz9E046VpUdmdnyPIRs6AM7MB+AIrQrWN7K5x1VBVJKG13b0CiiimZhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVyHhL/iV6/r/h88JHOLy2H/TOTkgewPH4119efeM5H0D4geE/EYdltLiVtIvBn5cScxE+mHByfpUSjdp9jopV+SnOm1dSS+TTun+a+Z6DRRRVnOFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRWX4i8Q6d4X0S41bVJvLt4R0HLO3ZVHdj6UAVfF3iuy8IaMb66Vpp5GEVrax8yXEp+6ij+vavLtcm8SeJNHXwReSxXnijU51vrgIAsOiwBlZQWXktwB3PzHrxmO5vtZm1y11m9s1uPGmpoU0LR35j0q3PWeX0bHJJ/xA9P8GeELfwlpjoZmu9Sun86/vpOXuJT1JPoMnA7fUmgDoYUeOCNJJPNkVQGfGNxxycds0+iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigArlfHXiG98N2mjXNmIjHcavb2t15i5xC5IYjng9Oa6quB+MyMPhnf3SDMlnNb3C/VZU/oTQB31FNR1kjWRDlWAIPsadQAUUUUAFFFFABRRRQAVHPPFbW8txO6xwxIXd2PCqBkk/hUlcD8Ubye7sNO8IafIVvvENx9nZl6x26/NM/wD3zx9CaAM7SfiP4w1fTo9UtPh3PcaZOWa3mj1K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0OuY8ZeC4PFyWEo1C707UNOlM1nd2xGY2OM5B6jgccdOvWgCj8JrW+sPhrpdjqNrPbXVsZo2jmjKNgSvtODzggiu1rzk6/478Inbr+jp4i01f+YhpK7Z1Hq8B6n/AHeBXT+HPGnh7xXGTpGpRTSr9+3b5JU9cocH8elAG/RVLVtXsNC0ufUtTuo7azgXdJK/QdgPck8ADk15N4k8UXnibTGv9Wurjwz4Mc7Y1Axf6r/sovVVP6jrweADo9d8f3Wo30+h+CIob2+hyLvU5TizsB3LN0ZhzwP1wRWTpeqT+LvijoOo6SjX1ho1pPbalqyR+XBNIydIwTz8wB4z19OSzQ/BV/4qsIINRsW8O+D4iGt9CgJWa6H9+4Yc89dvX15GT6rZWVrptnFZ2VvFb20K7Y4olCqo9gKAJ6KKKACiiigAooqve31pp1s1xe3MVvCvV5WCj9aG7bjjFydkrsmdtiM2CcDOB1Nc34As7iy8GWUd3DJDcs0kkiSKVYEyMeQfbFU7nxBpniE2kiLNLo0F3tupZYWWGTKPtJz1UNjOeAdua0/DogF3qZ09VXSzInkeWMRltvzlO23p04zn3rFSUppr+v6selKhUo4adOaabab07XVvX3r2tsb9FFFbHmBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFcx4j+H/hzxPILi9sRFfKcpfWreVOh7HeOuPfNdPRQB5hf6R8RtAtHtNPm0/wAX6dJhVh1VQk8fcFmJCyAEA5Jz0xWx4b8Am31NfEPii7GseISMrIw/c2g/uwp0GP73X6ZOe3ooAKKKKACiiigAqtqF9BpmnXN/dFlt7aJpZCqFiFUZJAHJ4FWaKAPOT4o8aeLfl8LaGNI09v8AmKayuHI9Y4Rz7gnIPtW1pvgSzR4rrXbubXNQVQDNd/cB77Y/uge3NdZRUyipbo1pV6lK/s5NX00EVVRQqKFUDAAGABS0UVRkFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf//Z", - "image/png": "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", - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Generate Mol Viz\n", - "from rdkit import Chem\n", - "from rdkit.Chem import Draw\n", - "\n", - "input_ids = tokenizer(\"\", return_tensors=\"pt\").input_ids.to(device)\n", - "gen = model.generate(input_ids, max_length=25, top_k=50, temperature=1, do_sample=True, pad_token_id=tokenizer.pad_token_id)\n", - "generatedmol = tokenizer.decode(gen[0], skip_special_tokens=True)\n", - "\n", - "test = generatedmol.replace(' ', '')\n", - "csmi_gen = sf.decoder(test)\n", - "print(csmi_gen)\n", - "mol = Chem.MolFromSmiles(csmi_gen)\n", - "\n", - "# Draw the molecule\n", - "Draw.MolToImage(mol)" - ] - }, - { - "cell_type": "markdown", - "id": "ab1ec3d4", - "metadata": {}, - "source": [ - "# Testing the MTP Generation" - ] - }, { "cell_type": "code", - "execution_count": 21, - "id": "db78ea04", + "execution_count": 10, + "id": "56628930", "metadata": {}, "outputs": [ { @@ -742,14 +749,14 @@ "output_type": "stream", "text": [ "Using MTP-specific generation...\n", - "Generated SELFIES: [O][=C][Branch1][=Branch2][C][=C][C][=C][C][=C][Ring1][=Branch1][C][=C][C][=C][C][=C][C][Ring1][=Branch1][=C][Ring1][#Branch2][C][O]\n", - "Decoded SMILES: O=C(C1=CC=CC2=C1)C=C3C=CC=CC3=C2CO\n" + "Generated SELFIES: .[F][C][=C][C][=C][C][=C][Ring1][=Branch1][C][N][C][C][N][Branch1][#Branch2][C][C][=C][C][=C][C][=C][Ring1][=Branch1][C][C][Ring1][=N]\n", + "Decoded SMILES: FC1=CC=CC=C1CN2CCN(CC3=CC=CC=C3)CC2\n" ] }, { "data": { - "image/jpeg": "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", - "image/png": "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", + "image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAorz7xPrfiDWfGcPhTwjqUdhNaw/adTvngWYQg/6uPawxuPXtxjng0v/CMfEf8A6KJbn/uCRf40AegUV5//AMI38Sf+h/tP/BNH/jR/wjvxKHH/AAndifc6Qn+NAHoFFecXug/FOO0le08Z6dNMqlkjbTETcR2zzjPTpXSeB/E6+LPC9tqDJ5V4hMF7BjBinXh1I7c8j2IoA6OiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACsTxb4hi8L+G7vVHTzZUXbbwA8zSn7qD6n07Zrbrz63/4rn4gtdn59C8OyFIf7txed29wnb3we9dWGoKo5Sm7Rirv9EvNvT8ehMnbY1fh94Zn8PaA02pN5ut6lIbzUZT1Mrc7foo4x064611lFFcpQUUUUAFeb38b+BfiXHqsaldB8RsIL0D7tvdj7kh7AP0PvkntXpFZniHQ7XxJoN5pN4P3VxGV3Y5RuqsPcHB/CrpqDmlUdlfX0E/I06K5HwBrl1qGlz6TqxxrWkSfZbsE8uB9yT3DDv3INddV16MqFR05dPx7P0a1QJ3VwooorEYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFYfi/xLb+EvDN3q06+Y8a7YIR1mlbhEH1P6ZPagCS98WeG9OvHs77xBpVrdJjfDPexo65GRlScjgiof+E38J/8AQ0aL/wCDCL/4qud8H/DfTIND+1+J9JsNS13UJGu76W6tklKyOclF3A4Azjjvmt7/AIQHwd/0Kui/+AEX/wATQBZ/4S7w0QD/AMJDpOCAR/psfI/76py+K/Djfd1/Sj9LyP8AxqufA3hM4z4b0ngAD/RE4A/Cm/8ACCeEsg/8I3pQI6YtUH9K7YrBW1cr/In3jHHjh59O8UpcWaxXGmpePbKJCBcxQs6FgRyCGTBx03Ke9dJ4c0iy0Pw/Z2GnxeVbom4AnJJbkknucmuW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", + "image/png": "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", "text/plain": [ "" ] @@ -809,8 +816,55 @@ " img = Draw.MolToImage(mol)\n", " display(img) # Use display() in Jupyter notebooks\n", "else:\n", - " print(\"โŒ Could not create molecule from generated SMILES\")" + " print(\"โŒ Could not create molecule from generated SMILES\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "0dc9e278", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Standard Generation Test ---\n", + "Generated SELFIES 1: [C]\n", + "Generated SELFIES 2: [C]\n", + "Generated SELFIES 3: [C] .[C] [=N] [C] [Branch1] [Ring1] [O] [C] [=C] [C] [Branch1] [C] [F] [=C] [Ring1] [=Branch2] [O]\n" + ] + } + ], + "source": [ + "print(\"\\n--- Standard Generation Test ---\")\n", + "input_ids = tokenizer(\" [C]\", return_tensors=\"pt\").input_ids.to(device)\n", + "with torch.no_grad():\n", + " model.set_mtp_training(False)\n", + " gen = model.generate(\n", + " input_ids,\n", + " max_length=25,\n", + " top_k=50,\n", + " top_p=0.9,\n", + " temperature=1.0,\n", + " do_sample=True,\n", + " pad_token_id=tokenizer.pad_token_id,\n", + " eos_token_id=tokenizer.eos_token_id,\n", + " num_return_sequences=3,\n", + " )\n", + " for i, sequence in enumerate(gen):\n", + " result = tokenizer.decode(sequence, skip_special_tokens=True)\n", + " print(f\"Generated SELFIES {i+1}: {result}\")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "edf549c4", + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": {