role-model / roleR

R package implementing the RoLE model
https://role-model.github.io/roleR
GNU General Public License v3.0
1 stars 2 forks source link

get conda env working and figure out a plan for msprime install #118

Open ajrominger opened 1 year ago

ajrominger commented 1 year ago

here's a possible strategy to try:

in zzz.R define .onLoad function to do the following:

  1. check for r-reticulate environment
  2. check for needed python packages
  3. run reticulate::install_miniconda if neccesary
  4. if install fails prompt user to consider running reticulate::uninstall_miniconda and then have a function they can run to set everything up again

then when actually running the function, have something that

  1. sets up the conda env we want
  2. imports the packages we need
  3. BUT...do we want the conda env and package import to be in the runRole function or in the global env and established on import or on attachment???
ajrominger commented 1 year ago

example from package transforEmotion the define a set-up function:

#' Install Miniconda
#'
#' @description Installs miniconda
#'
#' @details Installs miniconda using \code{\link[reticulate]{install_miniconda}}
#'
#' @author Alexander P. Christensen <alexpaulchristensen@gmail.com>
#' 
#' @export
#'
# Install miniconda
# Updated 13.04.2022
setup_miniconda <- function()
{

  # Install miniconda
  path_to_miniconda <- try(
    reticulate::install_miniconda(),
    silent = TRUE
  )

  # Check for try-error
  if(any(class(path_to_miniconda) != "try-error")){

    # Give user the deets
    message("\nTo uninstall miniconda, use `reticulate::miniconda_uninstall()`")

  }

}

and then use it in the primary function of the package like this:

# Check for classifiers in environment
if(exists(transformer, envir = as.environment(envir))){
    classifier <- get(transformer, envir = as.environment(envir))
}else{

    # Run setup for miniconda
    setup_miniconda()

    # Check if 'transformers' module is available
    if(!reticulate::py_module_available("transformers")){

        # Run setup for modules
        setup_modules()

        # Import 'transformers' module
        message("Importing transformers module...")
        transformers <- reticulate::import("transformers")

    }else{

        # Check for 'transformers' module in environment
        if(exists("transformers", envir = as.environment(envir))){
            transformers <- get("transformers", envir = as.environment(envir))
        }else{

            # Import 'transformers' module
            message("Importing transformers module...")
            transformers <- reticulate::import("transformers")

        }

    }

    # Check for custom transformer
    if(transformer %in% c(
        "cross-encoder-roberta", "cross-encoder-distilroberta", "facebook-bart"
    )){

        # Load pipeline
        classifier <- switch(
            transformer,
            "cross-encoder-roberta" = transformers$pipeline("zero-shot-classification", model = "cross-encoder/nli-roberta-base"),
            "cross-encoder-distilroberta" = transformers$pipeline("zero-shot-classification", model = "cross-encoder/nli-distilroberta-base"),
            "facebook-bart" = transformers$pipeline("zero-shot-classification", model = "facebook/bart-large-mnli")

        )

    }else{

        # Custom pipeline from huggingface
        # Try to catch non-existing pipelines
        pipeline_catch <- try(
            classifier <- transformers$pipeline("zero-shot-classification", model = transformer),
            silent = TRUE
        )

        # Errors
        if(any(class(pipeline_catch) == "try-error")){

            # Model exists but no pipeline
            if(isTRUE(grepl("Tokenizer class", pipeline_catch))){

                stop(
                    paste(
                        "Transformer model '",
                        transformer,
                        "' exists but does not have a working pipeline yet.\n\nTry a default model or select a model from huggingface: <https://huggingface.co/models?pipeline_tag=zero-shot-classification>\n",
                        sep = ""
                    )
                )

            }else{
                stop(pipeline_catch)
            }

        }

    }

}

# Load into environment
if(isTRUE(keep_in_env)){

    # Keep transformer module in environment
    assign(
        x = "transformers",
        value = transformers,
        envir = as.environment(envir)
    )

    # Keep classifier in environment
    assign(
        x = transformer,
        value = classifier,
        envir = as.environment(envir)
    )
}
ajrominger commented 1 year ago

also check out:

ajrominger commented 1 year ago

here's a potentially really great approach the connor thought of: https://github.com/bodkan/slendr/blob/main/R/zzz.R